oralce 查询速度

猫熊 2014-12-11 03:30:43

前几天从一张表中备份出来一年的数据;
查询速度变慢了;
重建索引也是慢;
快的 1,2秒; 慢的几十分钟;
执行计划如下;
值不同,执行计划也不同,速度也不同;
左边的要快很多;

怎么破???
...全文
158 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
猫熊 2014-12-15
  • 打赏
  • 举报
回复
嗯,有影响;
猫熊 2014-12-12
  • 打赏
  • 举报
回复
引用 1 楼 wildwave 的回复:
备份出来一年的数据是什么意思? 数据量变化的话,建议将几张大表的统计信息用dbms_stats.gather_table_stats重新采集下
引用 2 楼 yangxuan992 的回复:
[quote=引用 1 楼 wildwave 的回复:] 备份出来一年的数据是什么意思? 数据量变化的话,建议将几张大表的统计信息用dbms_stats.gather_table_stats重新采集下
同意 大量的nested loop连接,大量的走索引,你看一看cardinality列,是否与你的数据表记录数一致,不一致就要重新分析一下 另外问一句,你是查询备份表慢吧?如果是那肯定是表信息没有分析的原因。[/quote] 一直在开会,没注意看; 备份一年 =》》》 将2012年的数据 插入到一张新表中;create table as select ........... 将原表2012年的数据delete 掉; 数据量大约在1000w左右吧; 执行计划A: 很快的不到1秒 左边 先根据 发货节点、箱号 查询库存(这里的数据两非常少,一般一条,不会有重复的), 再去查询 订单表(有唯一索引,对应1条),再去 查询目的节点 信息、区域等; 执行计划B: 几十分钟; 先根据 区域,查询节点,在查询订单目的点(订单12年的数据delete掉了,还有3000w左右,数据不少; 目的点有索引,是组合索引,lead列不在 条件中,)在去根据订单表id查询库存表, 执行计划B,一个是数据量大,一个条件是在组合索引中,循环嵌套的话,估计死在那里了; delete订单表之前的执行计划没有留意; 区域下的节点数据是不一样的; 执行计划A:区域节点在600 执行B :节点在200左右; 但不知为何 表的查询顺序区别这么大;
猫熊 2014-12-12
  • 打赏
  • 举报
回复
两种执行计划,完全不用的表查询顺序 A: -----------发货点===》目的点 的查询顺序 快 (发货点、物品号)==》库存表===(通过订单id)==》订单表====(目的节点)====》节点===》区域 B: --------------目的点===》发货点的 查询顺序 慢 (区域)===》节点==》订单表目的地==(订单ID)==库存表 最终结果只有一个,但中间查询数据肯定不一样; 文笔不好,希望对遇到类似问题的人有点帮助
小灰狼W 2014-12-12
  • 打赏
  • 举报
回复
恐怕后一个语句算不上改进,如果主要过滤条件不在SDATA里,反而会拖慢效率 从字面上看,大表order_detail中,左边的执行计划走了该表的unique索引,右边的走了该表is_delete字段上的索引的范围扫描 如果is_delete取值只有'Y'和'N',且取值为'N'的记录不在少数,就会产生效率问题 可以找一下产生这个问题的原因,重新采下order_detail表的统计信息,确认该索引是否只包含is_delete字段 如果还不能解决,确定该索引不需要以后,删掉它
猫熊 2014-12-12
  • 打赏
  • 举报
回复
订单的目的节点 有索引; 删除area.id 条件,在没有直接条件的情况下,不会先查询区域下节点的信息,在查询订单表 ,在查询库存表; 执行计划与 左边类似
猫熊 2014-12-12
  • 打赏
  • 举报
回复
引用 4 楼 wildwave 的回复:
执行计划没有贴全 从执行计划上看,貌似系统认为后者的数据量才更小 重新采下统计信息
表、索引最后一次分析记录是11年的; 1、需要重新采集系统信息; 2、感觉是索引多了的问题;(订单表:目的地CODE索引) 原始sql; 当AREA.ID in(3) 时,或者(3,4,5,25)时,对应上面左边的执行计划,执行快, ;区域下节点多 当AREA.ID IN(25) 时,对应上边右边的执行计划,执行慢;区域下节点少 但AREA.ID in(3,4) , 执行计划和右边类似(表查询顺序), 执行慢;

SELECT DISTINCT STOCK_BOX.ID           AS ID,
                STOCK_BOX.NODE_ID      AS STORAGE_NODE_ID,
                STOCK_BOX.NODE_ID      AS FROM_NODE,
                STOCK_BOX.BUSINESS_ID,
                STOCK_BOX.BOX_BARCODE  AS BOX_CODE,
                STOCK_BOX.LOT1         AS LOTS,
                STOCK_BOX.LENGTH       AS LENGTH,
                STOCK_BOX.HEIGHT       AS HEIGHT,
                STOCK_BOX.WIDTH        AS WIDTH,
                STOCK_BOX.WEIGHT       AS WEIGHT,
                STOCK_BOX_PART.PART_ID AS PART_ID,
                STOCK_BOX_PART.QTY     AS QUANTITY,
                PART.PART_CODE         AS PART_CODE,
                PART.PART_NAME         AS PART_NAME,
                FN.NODE_CODE           AS FROM_NODE_CODE,
                FN.NODE_NAME           AS FROM_NODE_NAME,
                TN.ID                  AS TO_NODE,
                TN.NODE_NAME           AS TO_NODE_NAME,
                ORDER_DETAIL.ID        as DETAIL_ID
  from STOCK_BOX_PART
 INNER JOIN STOCK_BOX
    ON STOCK_BOX.ID = STOCK_BOX_PART.STOCK_BOX_ID
 INNER JOIN PART
    ON STOCK_BOX_PART.PART_ID = PART.ID
  JOIN NODE FN
    ON FN.ID = STOCK_BOX.NODE_ID
  JOIN ORDER_DETAIL             ------------数据量大
    ON ORDER_DETAIL.ID = STOCK_BOX_PART.ORDER_DETAIL_ID
   AND ORDER_DETAIL.IS_DELETE = 'N'
  JOIN NODE TN
    ON TN.NODE_CODE = ORDER_DETAIL.RECEIVE_NODE_CODE
   AND TN.IS_DELETE = 'N'

  JOIN AREA_NODE
    ON AREA_NODE.NODE_ID = TN.ID
  JOIN AREA
    ON AREA.ID = AREA_NODE.AREA_ID
   AND AREA.IS_DELETE = 'N'
   AND AREA_NODE.IS_DELETE = 'N'
   AND AREA.ID in (4)                   -----------删掉这里的area.id 条件,查询结果返回area.id,在程序中判断
 WHERE STOCK_BOX.IS_DELETE = 'N'
   AND PART.IS_DELETE = 'N'
   AND STOCK_BOX.NODE_ID = 2149
   AND STOCK_BOX.BUSINESS_ID = '3'
   AND STOCK_BOX.BOX_BARCODE = '33333333333333333333'
在不删除 索引的情况下,怕影响其他性能 第一种:删除area.id 条件,没有直接条件的情况下,不会先查询[color=#800000目的点的信息,查询订单表][/color] ,在查询库存表; 执行计划与 左边类似 第二种改进sql:

SELECT SDATA.*, PART.PART_CODE
  FROM (select DISTINCT STOCK_BOX.ID           AS ID,
                        STOCK_BOX.NODE_ID      AS STORAGE_NODE_ID,
                        STOCK_BOX.NODE_ID      AS FROM_NODE,
                        STOCK_BOX.BUSINESS_ID,
                        STOCK_BOX.BOX_BARCODE  AS BOX_CODE,
                        STOCK_BOX.LOT1         AS LOTS,
                        STOCK_BOX.LENGTH       AS LENGTH,
                        STOCK_BOX.HEIGHT       AS HEIGHT,
                        STOCK_BOX.WIDTH        AS WIDTH,
                        STOCK_BOX.WEIGHT       AS WEIGHT,
                        STOCK_BOX_PART.PART_ID AS PART_ID,
                        STOCK_BOX_PART.QTY     AS QUANTITY,
                        /*  PART.PART_CODE         AS PART_CODE,
                        PART.PART_NAME         AS PART_NAME,*/
                        FN.NODE_CODE AS FROM_NODE_CODE,
                        FN.NODE_NAME AS FROM_NODE_NAME,
                        /* TN.ID                  AS TO_NODE,
                        TN.NODE_NAME           AS TO_NODE_NAME,*/
                        STOCK_BOX_PART.ORDER_DETAIL_ID as DETAIL_ID
          from STOCK_BOX
         INNER JOIN STOCK_BOX_PART
            ON STOCK_BOX.ID = STOCK_BOX_PART.STOCK_BOX_ID
          JOIN NODE FN
            ON FN.ID = STOCK_BOX.NODE_ID
         WHERE STOCK_BOX.IS_DELETE = 'N'
           AND STOCK_BOX.NODE_ID = 100
           AND STOCK_BOX.BUSINESS_ID = '3'
           AND STOCK_BOX.BOX_BARCODE = '00000000300003058664') SDATA----这里每次查询结果只会有一条
  JOIN PART
    ON (SDATA.PART_ID = PART.ID)
  JOIN ORDER_DETAIL
    ON ORDER_DETAIL.ID = SDATA.DETAIL_ID
  JOIN NODE TN
    ON TN.NODE_CODE = ORDER_DETAIL.RECEIVE_NODE_CODE
   AND TN.IS_DELETE = 'N'
  JOIN AREA_NODE
    ON AREA_NODE.NODE_ID = TN.ID
  JOIN AREA
    ON AREA.ID = AREA_NODE.AREA_ID
 WHERE AREA.IS_DELETE = 'N'
   AND AREA.IS_DELETE = 'N'
   AND AREA_NODE.IS_DELETE = 'N'
   AND ORDER_DETAIL.IS_DELETE = 'N'
   AND AREA.ID in (25)
小灰狼W 2014-12-12
  • 打赏
  • 举报
回复
执行计划没有贴全 从执行计划上看,貌似系统认为后者的数据量才更小 重新采下统计信息
华而不实 2014-12-11
  • 打赏
  • 举报
回复
引用 1 楼 wildwave 的回复:
备份出来一年的数据是什么意思? 数据量变化的话,建议将几张大表的统计信息用dbms_stats.gather_table_stats重新采集下
同意 大量的nested loop连接,大量的走索引,你看一看cardinality列,是否与你的数据表记录数一致,不一致就要重新分析一下 另外问一句,你是查询备份表慢吧?如果是那肯定是表信息没有分析的原因。
小灰狼W 2014-12-11
  • 打赏
  • 举报
回复
备份出来一年的数据是什么意思? 数据量变化的话,建议将几张大表的统计信息用dbms_stats.gather_table_stats重新采集下
第一篇 Oracle管理配置 第1章 Oracle安装配置(教学视频:10分钟) 23 1.1 Oracle简介 23 1.1.1 数据库术语 23 1.1.2 主流数据库简介 24 1.1.3 Oracle数据库的特点 24 1.2 安装Oracle数据库 25 1.2.1 Oracle数据库的版本变迁及安装环境 25 1.2.2 安装过程 26 1.2.3 安装中需要注意的问题 27 1.3 本章小结 28 1.4 习题 28 第2章 Oracle常用工具(教学视频:7分钟) 29 2.1 Net Configuration Assistant(网络配置助手) 29 2.1.1 监听程序配置 29 2.1.2 命名方法配置 31 2.1.3 本地Net服务名配置 32 2.2 Net Manager(网络管理员) 34 2.3 本章实例 36 2.4 本章小结 38 2.5 习题 38 第3章 SQL Plus和PL/SQL(教学视频:11分钟) 39 3.1 SQL Plus与PL/SQL简介 39 3.2 使用SQL Plus 40 3.2.1 登录SQL Plus 40 3.2.2 SQL Plus输出结果的格式化 41 3.2.3 SQL Plus小结 46 3.3 PL/SQL 46 3.3.1 PL/SQL常用开发工具 46 3.3.2 开发一个简单的PL/SQL程序 48 3.4 本章实例 49 3.5 本章小结 50 3.6 习题 50 第二篇 Oracle数据库对象 第4章 Oralce数据库(教学视频:15分钟) 51 4.1 创建Oracle数据库 51 4.2 Oracle数据库的相关术语 52 4.2.1 数据库 53 4.2.2 数据库实例和SID 53 4.2.3 ORACLE_SID 54 4.3 Oracle数据库的备份与恢复 55 4.3.1 逻辑备份/恢复(导出/导入) 55 4.3.2 物理备份/恢复 56 4.3.3 利用PL/SQL Developer备份数据库 60 4.4 本章实例 61 4.5 本章小结 61 4.6 习题 62 第5章 Oracle数据表对象(教学视频:42分钟) 63 5.1 Oracle表空间 63 5.1.1 Oracle表空间简介 63 5.1.2 创建Oracle表空间 64 5.1.3 查看表空间 66 5.1.4 修改数据库默认表空间 67 5.1.5 修改表空间名称 68 5.1.6 删除表空间 69 5.2 创建Oracle数据表 70 5.2.1 利用工具创建数据表 70 5.2.2 利用工具查看数据表 71 5.2.3 利用命令创建数据表 72 5.2.4 利用命令查看表结构 72 5.3 修改Oracle数据表结构 73 5.3.1 利用工具修改数据表结构 73 5.3.2 利用命令修改数据表结构 74 5.4 删除数据表 75 5.4.1 利用工具删除数据表 76 5.4.2 利用SQL语句删除数据表 76 5.5 备份/恢复数据表 76 5.5.1 利用工具备份/恢复数据表 77 5.5.2 利用命令备份/恢复数据表 82 5.6 临时表 83 5.6.1 临时表简介 83 5.6.2 会话级临时表 84 5.6.3 事务级临时表 85 5.6.4 查看临时表在数据库中的信息 86 5.6.5 临时表的应用场景 86 5.7 特殊的表dual 87 5.7.1 分析dual表 87 5.7.2 dual表的应用场景 87 5.7.3 修改dual表对查询结果的影响 88 5.8 本章实例 89 5.9 本章小结 90 5.10 习题 90 第6章 约束(教学视频:43分钟) 91 6.1 主键约束 91 6.1.1 主键简介 91 6.1.2 创建主键约束 92 6.1.3 修改表的主键约束 94 6.1.4 主键应用场景 96 6.2 外键约束 97 6.2.1 外键简介 97 6.2.2 创建外键约束 97 6.2.3 级联更新与级联删除 100 6.2.4 修改外键属性 102 6.2.5 外键使用 104 6.3 唯一性约束 105 6.3.1 唯一性约束简介 105 6.3.2 创建唯一性约束 105 6.3.3 修改唯一性约束 107 6.3.4 唯一性约束的使用 108 6.4 检查约束 108 6.4.1 检查约束简介 108 6.4.2 创建检查约束 108 6.4.3 修改检查约束 110 6.4.4 检查约束的使用 111 6.5 默认值约束 111 6.5.1 默认值约束简介 112 6.5.2 创建默认值约束 112 6.5.3 修改默认值约束 113 6.6 本章实例 115 6.7 本章小结 116 6.8 习题 116 第7章 视图(教学视频:50分钟) 117 7.1 关系视图 117 7.1.1 建立关系视图 117 7.1.2 修改/删除视图 118 7.1.3 联接视图 120 7.1.4 编译视图 122 7.1.5 使用force选项强制创建视图 124 7.1.6 利用视图更新数据表 125 7.1.7 with check option选项 126 7.1.8 关系视图小结 128 7.2 内嵌视图 128 7.2.1 内嵌视图简介 128 7.2.2 内嵌视图的使用 128 7.2.3 内嵌视图小结 130 7.3 对象视图 131 7.3.1 对象视图简介 131 7.3.2 对象视图简介 131 7.4 物化视图 133 7.4.1 物化视图简介 133 7.4.2 物化视图的使用 133 7.4.3 物化视图的数据加载 135 7.4.4 物化视图的数据更新 135 7.4.5 查询重写 136 7.5 本章小结 136 7.6 本章实例 137 7.7 习题 137 第8章 函数与存储过程(教学视频:48分钟) 138 8.1 函数 138 8.1.1 函数简介 138 8.1.2 创建函数 139 8.1.3 函数中的括号 140 8.1.4 函数的参数 141 8.1.5 函数的确定性 142 8.1.6 典型函数举例 143 8.2 存储过程 144 8.2.1 存储过程简介 144 8.2.2 创建存储过程 144 8.2.3 存储过程的参数——IN参数 146 8.2.4 存储过程的参数——OUT参数 147 8.2.5 存储过程的参数——IN OUT参数 149 8.2.6 存储过程的参数——参数顺序 149 8.2.7 存储过程的参数——参数的默认值 152 8.2.8 存储过程的参数——参数顺序总结 153 8.3 程序包 153 8.3.1 规范 153 8.3.2 主体 155 8.3.3 调用程序包中的函数/存储过程 157 8.3.4 程序包中的变量 158 8.4 本章实例 159 8.5 本章小结 161 8.6 习题 161 …… 第9章 游标(教学视频:36分钟) 162 第10章 触发器(教学视频:58分钟) 178 第11章 序列(教学视频:28分钟) 206 第12章 用户角色与权限控制(教学视频:45分钟) 215 第三篇 Oracle中的SQL 第13章 Oracle数据类型(教学视频:21分钟) 231 第14章 Oracle中的函数与表达式(教学视频:111分钟) 240 第15章 Oracle中的控制语句(教学视频:16分钟) 282 第16章 SQL查询(教学视频:55分钟) 290 第17章 SQL更新数据(教学视频:34分钟) 319 第四篇 Oracle编程高级应用 第18章 数据库速度优化与数据完整性(教学视频:32分钟) 332 第19章 数据一致性与事务管理(教学视频:46分钟) 341 第20章 并发控制(教学视频:35分钟) 356 第21章 Oracle中的正则表达式(教学视频:29分钟) 369 第五篇 Oracle与编程语言综合使用实例 第22章 Oracle在Java开发中的应用(教学视频:38分钟) 376 第23章 Oracle在C#开发中的应用(教学视频:12分钟) 391

17,086

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧