我有两列Timestamp(2)START_DATE和END_DATE类型的索引以及带WHARE子句的查询,如:
WHERE C.START_DATE <= sysdate
AND sysdate <= C.END_DATE
解释计划使TABLE ACCESS FULL而不是Index range scan。
- 如果我将<=
更改为=
,则使用索引。
- 如果我将sysdate
更改为systimestamp
,那么在解释计划中会更糟:
SYS_EXTRACT_UTC(INTERNAL_FUNCTION(C.START_DATE))<=SYS_EXTRACT_UTC(SYSTIMESTAMP(6))
再次完全扫描。
- 使用TO_TIMESTAMP
带来所需的索引范围扫描:
WHERE C.START_DATE <= TO_TIMESTAMP ('10-Sep-02 14:10:10.123000', 'DD-Mon-RR HH24:MI:SS.FF')
AND TO_TIMESTAMP ('10-Sep-02 14:10:10.123000', 'DD-Mon-RR HH24:MI:SS.FF') <= C.END_DATE
但我需要使用当前日期。
有人可以解释为什么会这样吗?
编辑: 这些是查询的简化版本,但会出现相同的行为。 解释计划。
EXPLAIN PLAN FOR
select *
from communication c
WHERE C.CAMPAIGN_START_DATE <= sysdate
AND sysdate <= C.CAMPAIGN_END_DATE;
计划哈希值:4120205924
-------------------------------------------
| Id | Operation | Name |
-------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | TABLE ACCESS FULL| COMMUNICATION |
-------------------------------------------
EXPLAIN PLAN FOR
select *
from communication c
WHERE C.START_DATE = sysdate
AND sysdate = C.END_DATE;
计划哈希值:1474125303
-------------------------------------------------------------------
| Id | Operation | Name |
-------------------------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | TABLE ACCESS BY INDEX ROWID | COMMUNICATION |
| 2 | BITMAP CONVERSION TO ROWIDS | |
| 3 | BITMAP AND | |
| 4 | BITMAP CONVERSION FROM ROWIDS| |
| 5 | INDEX RANGE SCAN | COMMUNICATION_START_DT |
| 6 | BITMAP CONVERSION FROM ROWIDS| |
| 7 | INDEX RANGE SCAN | COMMUNICATION_END_TD |
-------------------------------------------------------------------
答案 0 :(得分:3)
你今天在时间戳上试了吗? TO_TIMESTAMP ('27-oct-15 14:10:10.123000'
?使用两天不同来比较查询是没有意义的。
我的猜测是使用当前日期,而<=
将意味着检查大多数行。这意味着使用索引不会带来太多好处
尝试此查询。
SELECT COUNT(*)
和
SELECT COUNT(*)
FROM ....
WHERE C.START_DATE <= sysdate
AND sysdate <= C.END_DATE
如果两个COUNT(*)
非常相似,则意味着使用索引没有任何好处,因为无论如何都需要扫描整个表。