【发布时间】:2017-01-15 13:25:56
【问题描述】:
我有一个查询将在一个有可能变得非常大的表上定期运行多次。我想确保我有一个可以处理我的查询以使其更快的索引。我对索引不是很熟悉,但到目前为止我有以下查询和索引:
update PERMISSION
SET EXPIRED_FLAG=1
where CASE WHEN VAL_END IS NULL THEN 1 ELSE 0 END =1
AND CURRENT_FLAG=1
AND SYSDATE+SUBSTR(TO_CHAR(SYSTIMESTAMP, 'TZR'),2,2)/24> VAL_START+30/1400
AND EXPIRED_FLAG=0;
我的索引看起来像:
CREATE INDEX NDX_VAL_DB_CLOSE ON PERMISSION
(CURRENT_FLAG, CASE WHEN VAL_END IS NULL THEN 1 ELSE 0 END, CASE WHEN EXPIRED_FLAG=0 THEN EXPIRED_FLAG END )
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 1M
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
LOGGING
LOCAL (
PARTITION NDX_VAL_FKTICKET_ID_PRT1
LOGGING
NOCOMPRESS
TABLESPACE IDX_PRT_01
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 1M
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
FREELISTS 1
FREELIST GROUPS 1
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
),
PARTITION NDX_VAL_FKTICKET_ID_PRT2
LOGGING
NOCOMPRESS
TABLESPACE IDX_PRT_02
PCTFREE 10
INITRANS 2
MAXTRANS 255
STORAGE (
INITIAL 1M
NEXT 1M
MAXSIZE UNLIMITED
MINEXTENTS 1
MAXEXTENTS UNLIMITED
PCTINCREASE 0
FREELISTS 1
FREELIST GROUPS 1
BUFFER_POOL DEFAULT
FLASH_CACHE DEFAULT
CELL_FLASH_CACHE DEFAULT
)
)
NOPARALLEL;
执行计划:
我想知道我的索引是否真的与查询匹配。从执行计划来看,我的索引似乎正在被使用,但我不能 100% 确定索引的条件是否有意义并且完全匹配更新查询。我可以对索引做些什么以使其与查询实际匹配,还是所有索引列都已被使用? (再次,我对索引完全陌生,这是一个分区表,所以我有点迷茫)
【问题讨论】:
-
各种谓词的选择性如何?我的猜测是,各种 1/0 谓词并不是特别有选择性,
val_start是查询中唯一合理选择性的谓词。也就是说,我猜val_start谓词减少了需要大量更新的行数,而其他谓词不会做很多。但那是我的猜测——你知道你的数据。表是如何分区的? -
在此表中,大多数条目的过期标志 = 1,只有少数条目 = 0,更少的条目将超过 30 分钟。至于当前标志上的分区,它由我不太熟悉的过程控制,但随着时间的推移和添加更多条目,将会有更多条目移动到当前 = 0 而不是当前的第二个分区= 1 在我关心的活动分区中。
-
我想我的实际问题是,考虑到更新查询的上下文,这个索引是否有意义,并且显示的更新查询中实际使用了所有参数(谓词)。
标签: oracle indexing partitioning sql-execution-plan