我已经为表的时间戳列创建了索引,但是当我在 Oracle 中查询和检查解释计划时,它正在执行全表扫描而不是范围扫描
下面是表的DDL脚本
CREATE TABLE EVENT (
event_id VARCHAR2(100) NOT NULL,
status VARCHAR2(50) NOT NULL,
timestamp NUMBER NOT NULL,
action VARCHAR2(50) NOT NULL
);
ALTER TABLE EVENT ADD CONSTRAINT PK_EVENT PRIMARY KEY ( event_id ) ;
CREATE INDEX IX_EVENT$timestamp ON EVENT (timestamp);
下面是用于获取解释计划的解释计划查询 -
EXPLAIN PLAN SET STATEMENT_ID = 'test3' for select * from EVENT where timestamp between 1620741600000 and 1621900800000 and status = 'CANC';
SELECT * FROM PLAN_TABLE WHERE STATEMENT_ID = 'test3';
这是oracle返回的解释计划 -
我不确定为什么索引在这里不起作用,而是即使在时间戳列上创建索引后它仍然进行全表扫描。
有人可以帮我解决这个问题吗?
戈登是正确的。您需要此索引来加速您向我们展示的查询。
CREATE INDEX IX_EVENT$timestamp ON EVENT (status, timestamp);
为什么?您的查询需要对
status
进行相等匹配,然后对 timestamp
进行范围扫描。如果无法使用索引进行相等匹配,Oracle 的优化器似乎已经决定扫描表比扫描索引更便宜。
为什么做出这样的决定?
谁知道呢?数十年来,数百名程序员一直在研究优化器。
谁在乎?只需使用正确的索引进行查询即可。
优化器是基于成本的。因此,从概念上讲,优化器将评估所有可用计划,估计成本,并选择估计成本最低的计划。成本是根据统计数据估算的。建立索引时会自动收集索引统计信息。然而,您的表格统计数据可能无法反映现实生活。 Active SQL Monitor 报告将帮助您诊断问题。
Oracle 优化器在决定使用什么索引时会考虑几个因素。例如:
您可能想要重新计算表统计信息和索引统计信息(请参阅https://www.dba-oracle.com/t_dbms_stats_gather_table_stats.htm),或者重建索引(
alter index IX_EVENT$timestamp rebuild online parallel 10; alter index IX_EVENT$timestamp noparallel;
),甚至通过创建来重建表类似的行按时间戳顺序重新排序。其他人通过使用 SQL 调优顾问获得更好的运气(在数据库服务器上运行 sqltrpt.sql,请参阅 https://dba12c.wordpress.com/2015/04/30/query-is-running-slow-2/ ,或从 SQL Developer 运行,请参阅 https://www.oracle.com/webfolder/technetwork/tutorials/obe/db/sqldev/r30/TuningAdvisor/TuningAdvisor.htm ),或者通过强制 Oracle 使用索引像这样的优化器提示(https://docs.oracle.com/cd/B10500_01/server.920/a96533/hintsref.htm):
select /*+ index(event IX_EVENT$timestamp) */ * from event where ...