任何人都有关于如何处理以下查询的构建索引的指导?查询按预期工作,但我似乎无法绕过全表扫描。使用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))
答案 0 :(得分:1)
(deal_num)上的索引将极大地帮助子查询。实际上,(deal_num,locked)上的索引将允许子查询完全避免表本身。
您应该期望对主查询进行全表扫描,因为它会过滤未编入索引的状态(并且很可能不会从索引中受益,除非'NEW'是状态相当罕见的值)。
答案 1 :(得分:0)
我认为对于外部子查询的每次运行,它都会运行一次内部子查询(内部不存在...)。
这将是性能受到影响的地方 - 它将遍历user_stage_volume中每一行的所有user_stage_volume,即O(n ^ 2),n是usv中的行数。
另一种方法是为内部子查询创建一个视图,并使用该视图,或者使用WITH命名临时视图。