我有一個怪物遺留查詢是在我的程序的核心, 查詢需要太多的時間,是什麼讓它跑得更快的最佳方式? 我用的Oracle 11g優化SQL查詢
SELECT *
FROM (SELECT COUNT(*) AS countme,
string_value ,
name ,
property_id ,
category_id
FROM (SELECT DISTINCT a.string_value,
a.name ,
a.property_id ,
b.product_id ,
a.category_id
FROM filter_criterias a
JOIN product_properties b
ON (
a.property_id = b.property_id
AND
(
(
isnumber(b.value) IS NOT NULL
AND isnumber(a.range_bottom) IS NOT NULL
AND isnumber(a.range_top) IS NOT NULL
AND
(
a.range_bottom >a.range_top
AND b.value >= a.range_bottom
OR a.range_bottom<=a.range_top
AND b.value >= a.range_bottom
AND b.value <=a.range_top
)
)
)
)
JOIN PRODUCT_CATEGORY prc
ON (
prc.sku = b.product_id
AND prc.category_id = a.category_id
)
JOIN PRODUCT pr
ON (
b.product_id = pr.SKU
AND pr.visible = '1'
)
)
GROUP BY (string_value, name, property_id,category_id)
UNION
SELECT COUNT(*) AS countme,
string_value ,
name ,
property_id ,
category_id
FROM (SELECT DISTINCT a.string_value,
a.name ,
a.property_id ,
b.product_id ,
a.category_id
FROM filter_criterias a
JOIN product_properties b
ON (
a.property_id = b.property_id
AND
(
(
a.name= b.value
)
)
)
JOIN PRODUCT_CATEGORY prc
ON (
prc.sku = b.product_id
AND prc.category_id = a.category_id
)
JOIN PRODUCT pr
ON (
b.product_id = pr.SKU
AND pr.visible = '1'
)
)
GROUP BY (string_value, name, property_id,category_id)
)
ORDER BY 5,4,3,2
這說明計劃
"Optimizer" "Cost" "Cardinality" "Bytes" "Partition Start" "Partition Stop" "Partition Id" "ACCESS PREDICATES" "FILTER PREDICATES"
"SELECT STATEMENT" "ALL_ROWS" "1298" "2" "542" "" "" "" "" ""
"SORT(ORDER BY)" "" "1298" "2" "542" "" "" "" "" ""
"VIEW" "" "1297" "2" "542" "" "" "" "" ""
"SORT(UNIQUE)" "" "1297" "2" "74" "" "" "" "" ""
"UNION-ALL" "" "" "" "" "" "" "" "" ""
"HASH(GROUP BY)" "" "661" "1" "37" "" "" "" "" ""
"VIEW" "" "659" "1" "37" "" "" "" "" ""
"HASH(UNIQUE)" "" "659" "1" "95" "" "" "" "" ""
"NESTED LOOPS" "" "" "" "" "" "" "" "" ""
"NESTED LOOPS" "" "658" "1" "95" "" "" "" "" ""
"HASH JOIN" "" "493" "1" "81" "" "" "" ""B"."PRODUCT_ID"=TO_NUMBER("PRC"."SKU") AND "A"."CATEGORY_ID"=SYS_OP_C2C("PRC"."CATEGORY_ID")" ""
"HASH JOIN" "" "369" "2" "128" "" "" "" ""B"."PROPERTY_ID"=TO_NUMBER("A"."PROPERTY_ID")" ""A"."RANGE_BOTTOM">"A"."RANGE_TOP" AND "A"."RANGE_BOTTOM"<=TO_NUMBER("B"."VALUE") OR "A"."RANGE_BOTTOM"<="A"."RANGE_TOP" AND "A"."RANGE_BOTTOM"<=TO_NUMBER("B"."VALUE") AND "A"."RANGE_TOP">=TO_NUMBER("B"."VALUE")"
"TABLE ACCESS(FULL) BNET.B_FILTER_CRITERIAS" "ANALYZED" "36" "28" "1148" "" "" "" "" ""ISNUMBER"(TO_CHAR("A"."RANGE_BOTTOM")) IS NOT NULL AND "ISNUMBER"(TO_CHAR("A"."RANGE_TOP")) IS NOT NULL"
"TABLE ACCESS(FULL) BNET.B_PRODUCT_PROPERTIES" "ANALYZED" "332" "12566" "289018" "" "" "" "" ""ISNUMBER"("B"."VALUE") IS NOT NULL"
"TABLE ACCESS(FULL) BNET.WLCS_PRODUCT_CATEGORY" "ANALYZED" "124" "129762" "2205954" "" "" "" "" ""
"INDEX(RANGE SCAN) BNET.WLCS_PROD_VISIBLE_IDX" "ANALYZED" "12" "6208" "" "" "" "" ""PR"."VISIBLE"='1'" ""
"TABLE ACCESS(BY INDEX ROWID) BNET.WLCS_PRODUCT" "ANALYZED" "164" "1" "14" "" "" "" "" ""B"."PRODUCT_ID"=TO_NUMBER("PR"."SKU")"
"HASH(GROUP BY)" "" "637" "1" "37" "" "" "" "" ""
"VIEW" "" "635" "1" "37" "" "" "" "" ""
"HASH(UNIQUE)" "" "635" "1" "91" "" "" "" "" ""
"HASH JOIN" "" "634" "1" "91" "" "" "" ""B"."PRODUCT_ID"=TO_NUMBER("PRC"."SKU") AND "A"."CATEGORY_ID"=SYS_OP_C2C("PRC"."CATEGORY_ID")" ""
"NESTED LOOPS" "" "" "" "" "" "" "" "" ""
"NESTED LOOPS" "" "509" "1" "74" "" "" "" "" ""
"HASH JOIN" "" "345" "1" "60" "" "" "" ""B"."PROPERTY_ID"=TO_NUMBER("A"."PROPERTY_ID") AND "A"."NAME"="B"."VALUE"" ""
"TABLE ACCESS(FULL) BNET.B_FILTER_CRITERIAS" "ANALYZED" "35" "11257" "416509" "" "" "" "" ""
"TABLE ACCESS(FULL) BNET.B_PRODUCT_PROPERTIES" "ANALYZED" "309" "251319" "5780337" "" "" "" "" ""
"INDEX(RANGE SCAN) BNET.WLCS_PROD_VISIBLE_IDX" "ANALYZED" "12" "6208" "" "" "" "" ""PR"."VISIBLE"='1'" ""
"TABLE ACCESS(BY INDEX ROWID) BNET.WLCS_PRODUCT" "ANALYZED" "164" "1" "14" "" "" "" "" ""B"."PRODUCT_ID"=TO_NUMBER("PR"."SKU")"
"TABLE ACCESS(FULL) BNET.WLCS_PRODUCT_CATEGORY" "ANALYZED" "124" "129762" "2205954" "" "" "" "" ""
不可能告訴,因爲我們不知道存在哪些索引。顯示解釋計劃可能是一個好的開始... –
@Daniel - 即使沒有計劃,我可以看到由於ISNUMBER數值被存儲爲字符串。這是造成表掃描。這就像嘗試通過吃豆類和在顯眼的地方握住zippo來膨脹熱氣球一樣。 – MatBailie
@Lasse V. Karlsen:我不認爲這個問題太局部。雖然有很多細節對其他人不重要,但將數字存儲爲字符串的核心問題適用於大量觀衆。 –