SQL查询的索引指南

| 任何人都有关于如何为以下查询建立索引的指南?该查询工作正常,但似乎无法绕过全表扫描。使用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;
请在注释中索取您可能需要的更多信息,然后我会进行编辑。 这是表的创建脚本。 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))
    
已邀请:
(deal_num)上的索引将极大地帮助子查询。实际上,在(deal_num,已锁定)上的索引将允许子查询完全避免使用表本身。 您应该期望对主查询进行全表扫描,因为它会过滤未建立索引的状态(并且除非很有可能是'NEW \',否则它很可能不会从建立索引中受益)。     
我认为它为外部子查询的每次运行都运行一次内部子查询(内部不存在...)。 那将是性能受到打击的地方-它会遍历user_stage_volume中每一行的所有user_stage_volume,即O(n ^ 2),n是usv中的行数。 一种替代方法是为内部子查询创建一个视图,然后使用该视图,或者通过使用WITH来命名一个临时视图。     

要回复问题请先登录注册