我想知道为什么对于某些查询,索引不可能加快查询处理速度?

问题描述 投票:0回答:1

我已经尝试解释和显示这个查询的执行计划。

解释计划

SELECT *
FROM LINEITEM
WHERE l_quantity = 6
   OR l_shipMode = 'MAIL';

SELECT * FROM table(dbms_xplan.display);

输出是。

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 98068815

------------------------------------------------------------------------------
| Id  | Operation     | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |   287K|    34M|  8802   (1)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| LINEITEM |   287K|    34M|  8802   (1)| 00:00:01 |
------------------------------------------------------------------------------

然后我创建了一个索引 l_quantityl_shipMode:

CREATE INDEX lineItemIdx ON LINEITEM(l_quantity, l_shipMode);

然后我再解释并展示执行计划。

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 98068815

------------------------------------------------------------------------------
| Id  | Operation     | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |   287K|    34M|  8802   (1)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| LINEITEM |   287K|    34M|  8802   (1)| 00:00:01 |
------------------------------------------------------------------------------

没有区别。现在的查询不应该使用索引吗?

sql indexing sqlplus
1个回答
1
投票

唉,大多数数据库的优化工作做得非常差劲。or 表达式(Oracle是个例外)。

你可以使用 union all:

SELECT li.*
FROM LINEITEM li
WHERE l_quantity = 6
UNION ALL
SELECT li.*
FROM LINEITEM li
WHERE l_shipMode = 'MAIL' AND l_quantity <> 6;

为此,你需要 两种 指数。 LINEITEM(l_quantity)LINEITEM(l_shipMode, l_quantity).


2
投票

在你的查询中,你有两个条件,并结合一个 OR 子句。

 WHERE l_quantity = 6
    OR l_shipMode = 'MAIL';

这就意味着,对于过滤标准的评价,指数为

 INDEX lineItemIdx ON LINEITEM(l_quantity, l_shipMode);

对于OR子句的两个部分中的每一部分都不能正常工作......。

所以查询需要全盘扫描,索引在没有用。

在这种情况下,索引只有在条件为

WHERE l_quantity = 6

WHERE l_quantity = 6
  AND l_shipMode = 'MAIL';

或者使用两个索引,然后重建查询,基于UNION的两个分离查询。

© www.soinside.com 2019 - 2024. All rights reserved.