我可以知道为什么索引不可能加速某些查询的查询处理吗?

May I know why its impossible for an index to speed up query processing for certain queries?

我已尝试解释并显示此查询的执行计划:

解释

的计划
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 |
------------------------------------------------------------------------------

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

唉,大多数数据库在优化 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)

在您的查询中,您有两个条件与 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

的两个分离查询的查询