dov*_*mir 3 sql optimization oracle11g
我有一个怪物遗留查询,这是我的程序的核心,查询需要太多时间,什么是使其运行更快的最佳方法?我用的是oracle 11g
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
Run Code Online (Sandbox Code Playgroud)
这是解释计划
"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" "" "" "" "" ""
Run Code Online (Sandbox Code Playgroud)
一个潜在的巨大问题来源是您必须使用ISNUMBER.
如果将数值存储为文本,然后使用诸如"x <= y"之类的操作,则会完成许多负面操作:
- 在使用字符串之前必须将字符串解析为数字
- 字符串的索引可能会承受与数字索引没有相似之处
- 如果索引无效,则会获得表扫描而不是索引搜索
我强烈建议将值存储为实数而不是字符串.不必使用ISNUMBER,不必转换每个值,因此实际上能够使用索引的组合可以具有极大的性能优势.
编辑
您刚刚添加的PLAN包含很多实例,TABLE ACCESS(FULL)其中一些实例与数值存储为字符串相关联.