【问题标题】:Index Guidance for SQL QuerySQL 查询的索引指南
【发布时间】:2011-08-05 00:46:23
【问题描述】:

有人对如何为以下查询构建索引有指导吗?查询按预期工作,但我似乎无法绕过全表扫描。使用 Oracle 11g。

SELECT   v.volume_id
  FROM   (  SELECT   MIN (usv.volume_id) volume_id
              FROM   user_stage_volume usv
             WHERE   usv.status = 'NEW'
                     AND NOT EXISTS
                           (SELECT   1
                              FROM   user_stage_volume kusv
                             WHERE   kusv.deal_num = usv.deal_num
                                     AND kusv.locked = 'Y')
          GROUP BY   usv.deal_num, usv.volume_type
          ORDER BY   MAX (usv.priority) DESC, MIN (usv.last_update) ASC) v
 WHERE   ROWNUM = 1;

请在 cmets 中请求您可能需要的更多信息,我会编辑。

这是表的创建脚本。 PK 是 VOLUME_ID。 DEAL_NUM 不是唯一的。

CREATE TABLE ENDUR.USER_STAGE_VOLUME
(
  DEAL_NUM       NUMBER(38)                     NOT NULL,
  EXTERNAL_ID    NUMBER(38)                     NOT NULL,
  VOLUME_TYPE    NUMBER(38)                     NOT NULL,
  EXTERNAL_TYPE  VARCHAR2(100 BYTE)             NOT NULL,
  GMT_START      DATE                           NOT NULL,
  GMT_END        DATE                           NOT NULL,
  VALUE          FLOAT(126)                     NOT NULL,
  VOLUME_ID      NUMBER(38)                     NOT NULL,
  PRIORITY       INTEGER                        NOT NULL,
  STATUS         VARCHAR2(100 BYTE)             NOT NULL,
  LAST_UPDATE    DATE                           NOT NULL,
  LOCKED         CHAR(1 BYTE)                   NOT NULL,
  RETRY_COUNT    INTEGER                        DEFAULT 0 NOT NULL,
  INS_DATE       DATE                           NOT NULL
)

ALTER TABLE ENDUR.USER_STAGE_VOLUME ADD (
  PRIMARY KEY
 (VOLUME_ID))

【问题讨论】:

  • user_stage_volume 表的主键是什么?如果不是deal_num,deal_num在这个表中是否唯一?也许发布 user_stage_volume 的创建脚本(至少包括查询中的列)会有所帮助。
  • 谢谢约翰。我已经更新了问题。

标签: sql indexing oracle11g


【解决方案1】:

(deal_num) 上的索引将极大地帮助子查询。事实上,(deal_num,locked) 上的索引将允许子查询完全避开表本身。

您应该期望对主查询进行全表扫描,因为它会过滤未编入索引的状态(并且很可能不会从编入索引中受益,除非“新”是一个相当罕见的状态值)。

【讨论】:

    【解决方案2】:

    我认为每次运行外部子查询都会运行一次内部子查询(内部不存在...)。

    这将是性能受到影响的地方 - 它将针对 user_stage_volume 中的每一行运行所有 user_stage_volume,即 O(n^2),n 是 usv 中的行数。

    另一种方法是为内部子查询创建一个视图并使用该视图,或者使用 WITH 命名一个临时视图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-05
      • 1970-01-01
      • 2014-09-24
      • 2012-08-05
      相关资源
      最近更新 更多