Sql le不一定自上而下地处理谓词,您可能会发现,有一天,当计划发生变化时,您的查询会失败。无法判断,因为我们不知道存在哪些索引。显示解释计划可能是一个好的开始…@Daniel-即使没有计划,我也可以看到由于ISNUMBER而将数值存储为字符串。这导致了表格扫描

Sql le不一定自上而下地处理谓词,您可能会发现,有一天,当计划发生变化时,您的查询会失败。无法判断,因为我们不知道存在哪些索引。显示解释计划可能是一个好的开始…@Daniel-即使没有计划,我也可以看到由于ISNUMBER而将数值存储为字符串。这导致了表格扫描,sql,optimization,oracle11g,Sql,Optimization,Oracle11g,le不一定自上而下地处理谓词,您可能会发现,有一天,当计划发生变化时,您的查询会失败。无法判断,因为我们不知道存在哪些索引。显示解释计划可能是一个好的开始…@Daniel-即使没有计划,我也可以看到由于ISNUMBER而将数值存储为字符串。这导致了表格扫描。这就像吃豆子,在显眼的地方拿着一个拉链,试图给热气球充气一样。@Lasse V.Karlsen:我认为这个问题不太本地化。尽管有很多细节对其他人来说并不重要,但将数字存储为字符串的核心问题适用于大量用户。在Oracle中设置NOCOUNT O


le不一定自上而下地处理谓词,您可能会发现,有一天,当计划发生变化时,您的查询会失败。

无法判断,因为我们不知道存在哪些索引。显示解释计划可能是一个好的开始…@Daniel-即使没有计划,我也可以看到由于ISNUMBER而将数值存储为字符串。这导致了表格扫描。这就像吃豆子,在显眼的地方拿着一个拉链,试图给热气球充气一样。@Lasse V.Karlsen:我认为这个问题不太本地化。尽管有很多细节对其他人来说并不重要,但将数字存储为字符串的核心问题适用于大量用户。
在Oracle中设置NOCOUNT ON
???
 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"   ""  ""  ""  ""  ""
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
            INNER 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
                )
            INNER JOIN PRODUCT_CATEGORY prc
                ON prc.sku = b.product_id
                AND prc.category_id = a.category_id
            INNER 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
        INNER JOIN product_properties b
            ON a.property_id = b.property_id
            AND a.name = b.value
        INNER JOIN PRODUCT_CATEGORY prc
            ON prc.sku = b.product_id
            AND prc.category_id = a.category_id
        INNER 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
select dbms_stats.create_extended_stats(null,'product_properties','(isnumber(value))') from dual;
select dbms_stats.create_extended_stats(null,'filter_criterias','(isnumber(range_bottom))') from dual;
select dbms_stats.create_extended_stats(null,'filter_criterias','(isnumber(range_top))') from dual;

--Must re-gather table stats for the extended stats to work
begin
    dbms_stats.gather_Table_stats(user, 'product_properties', no_invalidate => false);
    dbms_stats.gather_Table_stats(user, 'filter_criterias', no_invalidate => false);
end;
/