在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不走索引.的更多相关文章

  1. 什么样的 SQL 不走索引

    参考: MySQL 索引优化全攻略 索引建立的规则 1.能创建唯一索引就创建唯一索引 2.为经常需要排序.分组和联合操作的字段建立索引 3.为常作为查询条件的字段建立索引 如果某个字段经常用来做查询条 ...

  2. 诊断一句SQL不走索引的原因

    from http://www.itpub.net/thread-1852897-1-1.html 有论坛朋友在上面的帖子里问SQL为什么不走索引,正好这两天我也刚刚在看SQL优化,于是试着回答了一下 ...

  3. ORACLE 查询不走索引的原因分析,解决办法通过强制索引或动态执行SQL语句提高查询速度

    (一)索引失效的原因分析: <>或者单独的>,<,(有时会用到,有时不会) 有时间范围查询:oracle 时间条件值范围越大就不走索引 like "%_" ...

  4. Oracle执行计划不走索引的原因总结

    在Oracle数据库操作中,为什么有时一个表的某个字段明明有索引,当观察一些语的执行计划确不走索引呢?如何解决呢?本文我们主要就介绍这部分内容,接下来就让我们一起来了解一下. 不走索引大体有以下几个原 ...

  5. oracle查询不走索引的一些情况(索引失效)

    Oracle建立索引的目的是为了避免全表扫描,提高查询的效率. 但是有些情况下发现即使建立了索引,但是写出来的查询还是很慢,然后会发现是索引失效导致的,所以需要了解一下那些情况会导致索引失效,即查询不 ...

  6. oracle 不走索引的原因

    create table tb2 as select * from emp;alter table tb2 modify empno number(4) not null;翻到20W行 create ...

  7. 二十、oracle通过复合索引优化查询及不走索引的8种情况

    1. 理解ROWID ROWID是由Oracle自动加在表中每行最后的一列伪列,既然是伪列,就说明表中并不会物理存储ROWID的值:你可以像使用其它列一样使用它,只是不能对该列的值进行增.删.改操作: ...

  8. SQL语句优化、mysql不走索引的原因、数据库索引的设计原则

    SQL语句优化 1 企业SQL优化思路 1.把一个大的不使用索引的SQL语句按照功能进行拆分 2.长的SQL语句无法使用索引,能不能变成2条短的SQL语句让它分别使用上索引. 3.对SQL语句功能的拆 ...

  9. SQL SERVER中什么情况会导致索引查找变成索引扫描

    SQL Server 中什么情况会导致其执行计划从索引查找(Index Seek)变成索引扫描(Index Scan)呢? 下面从几个方面结合上下文具体场景做了下测试.总结.归纳. 1:隐式转换会导致 ...

随机推荐

  1. PHP 常用到的一些小程序

    1.计算两个时间的相差几天 $startdate=strtotime(“2009-12-09”); $enddate=strtotime(“2009-12-05”); 上面的php时间日期函数strt ...

  2. HTML&CSS----练习做网页

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. io资料

    jitsi red5 apache meeting2 openmeeting2 openfire http://www.onlycoder.net/ 在视频会议领域,有许多可以值得参考的开源项目,这些 ...

  4. UVa 11624 Fire!(BFS)

    Fire! Time Limit: 5000MS   Memory Limit: 262144KB   64bit IO Format: %lld & %llu Description Joe ...

  5. HDU 2091 空心三角形(模拟)

    把一个字符三角形掏空,就能节省材料成本,减轻重量,但关键是为了追求另一种视觉效果.在设计的过程中,需要给出各种花纹的材料和大小尺寸的三角形样板,通过电脑临时做出来,以便看看效果.   Input 每行 ...

  6. mapreduce运用

    测试环境:192.168.1.55 mongo 192.168.1.55:30001show dbsuse gwgps 测试目标,求出两个班的总数,人数,平均分数等.可以根据不同的业务需求,定制map ...

  7. Nginx 笔记与总结(16)nginx 负载均衡

    nginx 反向代理时,如果后端有多台服务器,就可以实现负载均衡. 实现原理:把多台服务器用 upstream 绑定在一起并起一个组名,然后 proxy_pass 指向该组. ngx_http_ups ...

  8. CentOs 6.6 安装配置 SVN

    ① 挂载光盘 mount /dev/cdrom /mnt/cdrom ② yum 安装 svn yum -y install subversion ③ 创建svn 版本库根目录 mkdir -p /w ...

  9. A20板子上的触摸屏设备号变化后解决

  10. $().html(value) vs $().empty().append(value)

    当需要清空某个dom结点内容时,我所知道的有两种方法: 1.Element.removeChild(child) // Removing all children from an element va ...