【问题标题】:Avoiding full Table scan in Oracle在 Oracle 中避免全表扫描
【发布时间】:2015-12-04 11:02:58
【问题描述】:

我有一个查询,它从包含数千个条目的整个表中获取最后 30 行。该表很大,因此执行数据库查询需要 5 分钟以上。如何避免对表进行全表扫描,使其仅扫描最后几行。我正在使用 Oracle 11g

SELECT DD,MODEL,CNT,SYS
  FROM DVCE_TAB
  WHERE DD >= TO_DATE('2015-08-09','YYYY-MM-DD')
  AND DD <= TO_DATE('2015-09-08','YYYY-MM-DD')
  AND SYS IN ('00','01')

DD 是日期,SYS 是设备的系统类型,MODEL 是设备的名称 DD 和 MODEL 是表的组合主键 TABLE 包含数千个条目,并包含 2010 年的数据 我只需要获取上个月的数据

【问题讨论】:

  • 你的 SQL 查询是什么?
  • 从表中选择 DD、COL2、COL3,其中 DD >= '2015-08-09' AND
  • 请编辑您的问题并在DVCE_TAB 中包含列的定义,以及在DVCE_TAB 中定义的任何索引。谢谢。
  • 数百万行在设计良好的数据库中不是问题。在表中添加索引,包括索引中的列 DD 和 SYS
  • @PavelGatnar - 他现在已经解决了。

标签: sql oracle11g


【解决方案1】:

我想到了一些想法:

1) 在 DD 和 SYS 列上定义索引:

CREATE INDEX DVCE_TAB_1
  ON DVCE_TAB (DD, SYS);

您可能需要在添加索引后收集表统计信息:

BEGIN
  DBMS_STATS.GATHER_TABLE_STATS(ownname => 'YOUR_SCHEMA_NAME',
                                tabname => 'DVCE_TAB');
END;

这可能就是您所需要的,但如果需要,您可以随时...

2) DD 列上的分区 DVCE_TAB。

CREATE TABLE DVCE_TAB
  (...column definitions...)
  PARTITION BY RANGE (DD) 
    INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
  PARTITION DVCE_TAB_P1 VALUES LESS THAN (TO_DATE('01-01-2000', 'DD-MM-YYYY'))); 

为此,您可能需要实际创建一个具有不同名称的新表,将所有现有数据从“旧”DVCE_TAB 复制到“新”DVCE_TAB,然后删除原始表并重命名“新”表到DVCE_TAB

祝你好运。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2019-07-17
    • 2014-02-07
    • 1970-01-01
    • 2015-01-12
    相关资源
    最近更新 更多