数据分布不均匀导致查询不走索引。

测试表

SQL> desc test
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ID                                                 NUMBER(38)
 NAME                                               VARCHAR2(30)

SQL> select * from test;

no rows selected

插入分布不均匀数据

SQL> declare i number;
  2  begin
  3  for i in 0 .. 10000 loop
  4  insert into test
  5  values(1,'a');
end loop;
  6    7  end;
  8  /

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

SQL> select count(*) from test;

  COUNT(*)
----------
     10001

SQL> declare i number;
  2  begin
  3  for i in 0 .. 10 loop
  4  insert into test
  5  values(2,'b');
  6  end loop;
  7  end;
  8  /

PL/SQL procedure successfully completed.

SQL> commit;

Commit complete.

SQL> declare i number;
  2  begin
  3  for i in 0 .. 20 loop
  4  insert into test
  5  values(3,'c');
  6  end loop;
  7  end;
  8  /

SQL> commit;

Commit complete.

查看索引情况

SQL> select INDEX_NAME,TABLE_NAME,COLUMN_NAME from user_ind_columns where TABLE_NAME='TEST';


INDEX_NAME                     TABLE_NAME                     COLUMN_NAME
------------------------------ ------------------------------ --------------------
TEST_IND                       TEST                           ID

查看执行计划发现没有查询语句没有走索引
  

SQL> select * from test where id=2;

        ID NAME
---------- ------------------------------
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b

11 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1357081020

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     5 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TEST |     1 |     5 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("ID"=2)

Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
         23  consistent gets
          0  physical reads
          0  redo size
        689  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         11  rows processed


发现是统计信息不正确,收集统计信息(dbms包有问题,只能用analyze 收集)
  

SQL> select num_rows from dba_tables where table_name='TEST';

  NUM_ROWS
----------
         2  

SQL> analyze table sys.test compute statistics;

Table analyzed.

SQL> select num_rows from dba_tables where table_name='TEST';

  NUM_ROWS
----------
     10033  

再次查询还是没有走索引


SQL> select * from test where id=2;

        ID NAME
---------- ------------------------------
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b

11 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 1357081020

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  3344 | 10032 |     7   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TEST |  3344 | 10032 |     7   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("ID"=2)


Statistics
----------------------------------------------------------
          8  recursive calls
          0  db block gets
         36  consistent gets
          0  physical reads
          0  redo size
        689  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          4  sorts (memory)
          0  sorts (disk)
         11  rows processed
         
         

查询有索引的列是可以走索引的

SQL> select id from test where id=2;

        ID
----------
         2
         2
         2
         2
         2
         2
         2
         2
         2
         2
         2

11 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3357096749

-----------------------------------------------------------------------------
| Id  | Operation        | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT |          |  3344 |  6688 |     6   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| TEST_IND |  3344 |  6688 |     6   (0)| 00:00:01 |
-----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("ID"=2)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          3  consistent gets
          0  physical reads
          0  redo size
        619  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         11  rows processed    

查看列统计信息直方图为none

SQL> select TABLE_NAME,COLUMN_NAME,HISTOGRAM from user_tab_col_statistics where TABLE_NAME='TEST';

TABLE_NAME                     COLUMN_NAME                    HISTOGRAM
------------------------------ ------------------------------ ---------------
TEST                           ID                             NONE
TEST                           NAME                           NONE
         

收集索引和列统计信息

SQL> analyze table sys.test compute statistics for table for all indexes for all columns;

Table analyzed.


SQL> select TABLE_NAME,COLUMN_NAME,HISTOGRAM from user_tab_col_statistics where TABLE_NAME='TEST';

TABLE_NAME                     COLUMN_NAME                    HISTOGRAM
------------------------------ ------------------------------ ---------------
TEST                           ID                             FREQUENCY
TEST                           NAME                           FREQUENCY

再次执行查询走了索引范围扫

SQL> select * from test where id=2;

        ID NAME
---------- ------------------------------
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b
         2 b

11 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 2216933833

----------------------------------------------------------------------------------------
| Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |    11 |    33 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TEST     |    11 |    33 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | TEST_IND |    11 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("ID"=2)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          5  consistent gets
          0  physical reads
          0  redo size
        742  bytes sent via SQL*Net to client
        523  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         11  rows processed

        

发布了47 篇原创文章 · 获赞 5 · 访问量 6900

猜你喜欢

转载自blog.csdn.net/whb234174124/article/details/102647226