【问题标题】:Indexing not working with column using range operations in oracle在 oracle 中使用范围操作索引不适用于列
【发布时间】:2021-08-13 22:35:59
【问题描述】:

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

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

谁能帮帮我。

【问题讨论】:

  • Oracle 已确定条件不够严格。 (status, timestamp) 上的索引可能会更好。
  • event 表中有多少行?其中有多少在查询指定的范围内具有时间戳值(顺便说一句,timestamp 是保留字,因此将其用作列名通常不是一个好主意,尤其是当数据类型不是 @987654328 时@)?其中有多少具有“CNC”状态?有多少同时具有您正在寻找的状态并且在时间戳范围内? Oracle 的基数估计是多少?

标签: sql oracle indexing query-optimization sql-execution-plan


【解决方案1】:

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

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

为什么?您的查询需要在status 上进行相等匹配,然后在timestamp 上进行范围扫描。由于无法使用索引进行相等匹配,Oracle 的优化器似乎认为扫描表比扫描索引更便宜。

为什么会这样决定?

谁知道?数十年来,数百名程序员一直致力于优化器。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-18
      • 2021-01-28
      • 1970-01-01
      • 1970-01-01
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多