对于以下查询。
ITEM_CTY_TAR_T
是一个包含超过 1000 万行的庞大表。我已经使用列 ITEM_NO, ITEM_TYPE, GA_CODE_IMP, GA_TYPE_IMP, TAR_NO
和 VALID_DATE_FROM
在此表上创建了主索引,但在解释此查询的计划时,优化器对表进行了完整扫描。应该创建什么索引来防止全扫描?
SELECT
t.item_no, t.item_type, t.BU_CODE_RU, t.tar_no,
VALID_DATE_FROM
FROM
(SELECT
tar.item_no, tar.item_type,
org.BU_CODE_RU, tar.tar_no, tar.VALID_DATE_FROM,
ROW_NUMBER() OVER (PARTITION BY tar.ITEM_NO, tar.ITEM_TYPE, org.BU_CODE_RU
ORDER BY VALID_DATE_FROM DESC, tar.tar_no DESC) AS RowNumber
FROM
(SELECT
item_no, item_type, tar_no, valid_date_from,
GA_CODE_IMP
FROM
ITEM_CTY_TAR_T tar
WHERE
GA_TYPE_IMP = 'CTY'
AND DATE '2023-08-06' >= TRUNC(tar.VALID_DATE_FROM)
AND DATE '2023-08-06' <= NVL(trunc(tar.VALID_DATE_TO), DATE'9999-12-31')
AND NVL(trunc(tar.DELETE_DATE), DATE '9999-12-31') > DATE '2023-08-06') tar,
(SELECT
BU_CODE_RU, GA_CODE_CTY
FROM
store_t
WHERE
BU_TYPE = 'SO' AND BU_CODE_RU IS NOT NULL) org
WHERE
org.GA_CODE_CTY = tar.GA_CODE_IMP) t
WHERE
rownumber = 1
您不希望索引用于此查询。仅当目标行与表大小的比率极小时,索引才比全表扫描更快。这里的情况不太可能是这样。
您正在查找在给定日期内处于活动状态的记录,但在大多数 2 类表中,即使不是表的大部分,这也是很重要的一部分。
GA_TYPE_IMP = 'CTY'
和 BU_TYPE = 'SO'
都不可能将结果范围缩小到足以证明索引使用的合理性。在这种情况下,全表扫描是最佳选择。
我建议您不要查看索引,而是暗示查询需要适度的并行性:
SELECT /*+ parallel(4) */
t.item_no, t. . . .