sql - Oracle 没有使用索引

标签 sql oracle12c

我有一个包含 100 万行的表 A。我有一个 poliespa 列的索引,其中包含“03”或“04”值。

CREATE INDEX A21 ON A(POLIESPA);

我的查询:

     SELECT polinpol,
       policdde,
       polipext,
       polidext,
       DECODE (polipext,  'T', polipdmx,  'A', polipdmx,  polipdix),
       politipo,
       polipdtu,
       DECODE (TO_NUMBER (RTRIM (LTRIM (polivmrd))), 0, 0, polivmrd),
       RTRIM (LTRIM (polipdtx)),
       polifeca
  FROM A
 WHERE poliespa = '03';

此 SQL 查询的解释计划进行全表扫描:

Plan hash value: 3450718889

----------------------------------------------------------------------------
| Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |        |   369K|    14M|  6615   (3)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| A      |   369K|    14M|  6615   (3)| 00:00:01 |
----------------------------------------------------------------------------

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

   1 - filter("POLIESPA"='03')

block - 41735:

SELECT COUNT (
           DISTINCT (SUBSTR (DBMS_ROWID.rowid_to_restricted (ROWID, 1), 1, 8)))
           blocks
  FROM A;

聚类:

SELECT index_name, clustering_factor
  FROM user_indexes
 WHERE index_name LIKE 'A21%'

INDEX_NAME  CLUSTERING_FACTOR
-----------------
A21         79247

1 row selected.

任何人都可以帮助我理解为什么优化器不使用索引或者为什么这是最好的方法?谢谢

编辑:

select count(*) from A
where poliespa = '03';

select count(*) from A
where poliespa = '04';

  COUNT(*)
----------
    221379
1 row selected.

  COUNT(*)
----------
    517095
1 row selected.

最佳答案

根据经验,如果子集是整个表的重要组成部分,那么使用索引没有什么好处。例如,类似于 20% 的东西(但这显然取决于情况)。

为什么?

想想当您通过索引访问这些数据时会发生什么 - 您一次访问一个索引 block (给定的比率可以与整个索引一样多)加上表的 block 。考虑到数据在表上的存储方式(聚类因子),索引访问最终可能会读取整个表。

表扫描可以更好更快,因为您可以使用多 block 读取顺序遍历所有 block ,而不是一次访问一个数据。

关于sql - Oracle 没有使用索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42694277/

相关文章:

php - 从 MySQL 中选择最新结果,其中有超过 1 行匹配 ID

sql - 哪些模式允许使用 sql 和 nosql 数据库进行对象持久化?

php - 如何从多个表添加数据

sql - 两个查询合并为一个子查询

MySQL 查询返回多个求和和分组列

sql - 如何使用 Oracle 12c 查询为 JSON 中的数组编制索引?

java - 文档获取添加/更新/删除时 Lucene 索引文件的更改?

oracle - Oracle 12c中没有用户名HR

oracle12c - Oracle dbms_scheduler 与 BYTIME 错误

Oracle12 : lpad function does not manage 2 bytes characters as Oracle11