我有一个包含 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/