Oracle直方图导致SQL不走索引.
在ITPUB 上看到一个帖子 http://www.itpub.net/thread-1875212-1-1.html
同一条SQL语句,只有查询条件不一样,查询返回的结果集都为0,一个走了全表扫描,一个走索引。查看全表扫描的SQL语句:
SQL走全表,产生了2422609个逻辑读,cost为535K
SQL> SELECT URL,YHZH,HFRZY,HFLR,SPURL,TPURL,YPURL,SCSJ,LY,JCSJ FROM YHXX_HFXX T
2 WHERE T.URL='http://club.kdnet.net/dispbbs.asp?id=10165509_boardid=1'
3 /
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 2068618995
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 917K| 266M| 535K (1)| 01:47:05 |
|* 1 | TABLE ACCESS FULL| YHXX_HFXX | 917K| 266M| 535K (1)| 01:47:05 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("T"."URL"='http://club.kdnet.net/dispbbs.asp?id=10165509_b oardid=1')
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
2422609 consistent gets
3 physical reads
5520 redo size
880 bytes sent via SQL*Net to client
458 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed
强制HINT使用索引,产生4个逻辑读,但是cost比全表扫描高:643K --显然这个计划才是最好的,但是为什么cost会这么高呢?下面会分析.
SQL> SELECT /*+index(YHXX_HFXX IDX_YHXX_HFXX_URL)*/
2 URL,YHZH,HFRZY,HFLR,SPURL,TPURL,YPURL,SCSJ,LY,JCSJ
3 FROM YHXX_HFXX
4 WHERE URL='http://club.kdnet.net/dispbbs.asp?id=10165509_boardid=1'
5 /
no rows selected
Execution Plan
----------------------------------------------------------
Plan hash value: 518948569
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 917K| 266M| 643K (1)| 02:08:48 |
| 1 | TABLE ACCESS BY INDEX ROWID| YHXX_HFXX | 917K| 266M| 643K (1)| 02:08:48 |
|* 2 | INDEX RANGE SCAN | IDX_YHXX_HFXX_URL | 917K| | 10735 (1)| 00:02:09 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("URL"='http://club.kdnet.net/dispbbs.asp?id=10165509_boardid=1')
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
4 consistent gets
0 physical reads
0 redo size
880 bytes sent via SQL*Net to client
458 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed
这里最奇怪的地方是当我们强制用hint的时候,虽然也走了索引,但是执行计划显示的estimated rows居然是917K和全部扫描一样多!
那就意味着优化器根据统计信息推断出里面所有的行的URL字段和where 条件里的URL='http://club.kdnet.net/dispbbs.asp?id=10165509_boardid=1' 值完全相同.这显然不可能。
这里我们注意到URL这个字符串值很长,在有直方图信息的时候,estimated row 首先考虑直方图信息,而且直方图只会取前32个字符生产一个浮点数,用这个浮
点数来计算直方图的统计信息。所以如果URL字段收集了直方图信息,并且URL的前32位完全相同,那么以为着在直方图统计的时候,会认为它们是一样的。
这里URL的前32都是“http://club.kdnet.net/dispbbs.as”,里面所有数据的URL都是针对同一个地址不同的id,这样就被认为是完全一样的了。
那么Oracle就认为数据要全部选出来,当然这种情况下扫描表是最好的了。因为选了第一个计划。
解决方案: 删除直方图统计信息
exec dbms_stats.gather_table_stats(ownname => 'YQJK',tabname => 'YHXX_HFXX',estimate_percent => 10,method_opt=>'for columns URL size 1',cascade=>TRUE) ;
删除直方图信息请参考 http://www.cnblogs.com/princessd8251/articles/3855707.html
Oracle直方图导致SQL不走索引.的更多相关文章
- 什么样的 SQL 不走索引
参考: MySQL 索引优化全攻略 索引建立的规则 1.能创建唯一索引就创建唯一索引 2.为经常需要排序.分组和联合操作的字段建立索引 3.为常作为查询条件的字段建立索引 如果某个字段经常用来做查询条 ...
- 诊断一句SQL不走索引的原因
from http://www.itpub.net/thread-1852897-1-1.html 有论坛朋友在上面的帖子里问SQL为什么不走索引,正好这两天我也刚刚在看SQL优化,于是试着回答了一下 ...
- ORACLE 查询不走索引的原因分析,解决办法通过强制索引或动态执行SQL语句提高查询速度
(一)索引失效的原因分析: <>或者单独的>,<,(有时会用到,有时不会) 有时间范围查询:oracle 时间条件值范围越大就不走索引 like "%_" ...
- Oracle执行计划不走索引的原因总结
在Oracle数据库操作中,为什么有时一个表的某个字段明明有索引,当观察一些语的执行计划确不走索引呢?如何解决呢?本文我们主要就介绍这部分内容,接下来就让我们一起来了解一下. 不走索引大体有以下几个原 ...
- oracle查询不走索引的一些情况(索引失效)
Oracle建立索引的目的是为了避免全表扫描,提高查询的效率. 但是有些情况下发现即使建立了索引,但是写出来的查询还是很慢,然后会发现是索引失效导致的,所以需要了解一下那些情况会导致索引失效,即查询不 ...
- oracle 不走索引的原因
create table tb2 as select * from emp;alter table tb2 modify empno number(4) not null;翻到20W行 create ...
- 二十、oracle通过复合索引优化查询及不走索引的8种情况
1. 理解ROWID ROWID是由Oracle自动加在表中每行最后的一列伪列,既然是伪列,就说明表中并不会物理存储ROWID的值:你可以像使用其它列一样使用它,只是不能对该列的值进行增.删.改操作: ...
- SQL语句优化、mysql不走索引的原因、数据库索引的设计原则
SQL语句优化 1 企业SQL优化思路 1.把一个大的不使用索引的SQL语句按照功能进行拆分 2.长的SQL语句无法使用索引,能不能变成2条短的SQL语句让它分别使用上索引. 3.对SQL语句功能的拆 ...
- SQL SERVER中什么情况会导致索引查找变成索引扫描
SQL Server 中什么情况会导致其执行计划从索引查找(Index Seek)变成索引扫描(Index Scan)呢? 下面从几个方面结合上下文具体场景做了下测试.总结.归纳. 1:隐式转换会导致 ...
随机推荐
- elasticsearch2.2 集群搭建各种坑
目前生产环境的es版本是1.0版本,需要升级到最新的2.2版本,于是在测试环境进行部署集群测试,在测试过程中遇到的坑相当多,下面详细介绍下. 1. 版本升级到2.2后,必须建一个单 ...
- 实例讲解Linux下的makefile
1.程序代码结构如下 makefile/ |-- Makefile |-- haha.c `-- hehe.c 1.1.需要被编译的源代码如下 $ cat haha.c #include " ...
- myeclipse 8.5最新注册码
myeclipse 8.5最新注册码(过期时间到2016年) Subscriber:huazai Subscription Code:uLR8ZC-855550-6156585630 ...
- [转]Web.config配置文件详解(新手必看)
本文转自:http://www.cnblogs.com/gaoweipeng/archive/2009/05/17/1458762.html 花了点时间整理了一下ASP.NET Web.config配 ...
- ie8默认主页/起始页无法修改
HKEY_CURRENT_USER\Software\Policies\Microsoft 展开Microsoft,查看其下是否包含子项 Internet Explorer? 若有,请删除.这一步应该 ...
- twitter storm源码走读之2 -- tuple消息发送场景分析
欢迎转载,转载请注明出处源自徽沪一郎.本文尝试分析tuple发送时的具体细节,本博的另一篇文章<bolt消息传递路径之源码解读>主要从消息接收方面来阐述问题,两篇文章互为补充. worke ...
- php isset() empty() 区别, 判断 变量存在与否神器
先看PHP手册: bool empty ( mixed $var ) 判断一个变量是否被认为是空的.当一个变量并不存在,或者它的值等同于FALSE,那么它会被认为不存在.如果变量不存在的话,empty ...
- Javascript 笔记与总结(2-5)window 对象
浏览器 window 对象(BOM)是浏览器宿主对象,和 js 语言无关. [window 对象的方法] window.alert(message); window.confirm(message); ...
- 使用Nsight查找CE3的渲染bug
工作临时的接的一个小任务,查找ce3引擎修改后在绘制上出的一点bug 在代码的底层调用代码做了一些修改后,场景里的绘制的问题,因为也是刚接触CE3代码,也只能通过Nsight来查找问题了. 首先用 ...
- Rochester Memory Hardware Error Research Project
http://www.cs.rochester.edu/research/os/memerror/