在 Oracle 中索引不适用于使用范围操作的列

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

我已经为表的时间戳列创建了索引,但是当我在 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返回的解释计划 -

我不确定为什么索引在这里不起作用,而是即使在时间戳列上创建索引后它仍然进行全表扫描。

有人可以帮我解决这个问题吗?

sql oracle indexing query-optimization sql-execution-plan
3个回答
0
投票

戈登是正确的。您需要此索引来加速您向我们展示的查询。

CREATE INDEX IX_EVENT$timestamp ON EVENT (status, timestamp);

为什么?您的查询需要对

status
进行相等匹配,然后对
timestamp
进行范围扫描。如果无法使用索引进行相等匹配,Oracle 的优化器似乎已经决定扫描表比扫描索引更便宜。

为什么做出这样的决定?

谁知道呢?数十年来,数百名程序员一直在研究优化器。

谁在乎?只需使用正确的索引进行查询即可。


0
投票

优化器是基于成本的。因此,从概念上讲,优化器将评估所有可用计划,估计成本,并选择估计成本最低的计划。成本是根据统计数据估算的。建立索引时会自动收集索引统计信息。然而,您的表格统计数据可能无法反映现实生活。 Active SQL Monitor 报告将帮助您诊断问题。


0
投票

Oracle 优化器在决定使用什么索引时会考虑几个因素。例如:

  1. 系统统计信息(即 CPU 和存储子系统的速度有多快,请参阅 https://blogs.oracle.com/optimizer/post/should-you-gather-system-statistics
  2. 表大小统计
  3. 栏目统计
  4. 指数统计
  5. 索引的聚类因子

您可能想要重新计算表统计信息和索引统计信息(请参阅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 ...

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