1
SELECT pe.prodtree_element_id prodID, pe.prodtree_element_name_s, li.line_name, av2.value
    FROM prodtree_element pe
    LEFT JOIN prodtree_link pl
        ON pe.prodtree_element_id = pl.to_prodtree_node_id
    LEFT JOIN line li
        ON pe.line_code = li.line_code
    INNER JOIN attribute_values av
        ON av.attribute_definition_id = #statusCode# 
    LEFT JOIN attribute_values av2
        ON pe.prodtree_element_id = av.prodtree_element_id
    WHERE pe.prodtree_element_func_type <> 'WIZARD'
        AND pe.prodtree_element_topo_type = 'NODE'

「#statusCode#」は、属性定義テーブルの ID と一致する静的 ID です (引数のために 22 としましょう)。問題は、クエリがかなりの時間内に終了するという大きな問題を抱えていることです。より大きな問題は、もっと早く終了する必要があることですが、レコードの数が膨大であり、取り戻さなければなりません (約 30 ~ 50,000)。複数のテーブルからのデータが必要ですが、そこから速度が低下し始めます。これは必要なもののほんの一部です。現在の「prodtree_elment_id」に一致する他のテーブル全体のデータも必要です。

私は ColdFusion を使用していますが、SQL Server 2005 でクエリを直接実行しても、このクエリを 15 ~ 30 分以上待機します (終了したとしても)。このクエリを高速化して、最大 5 分以下にする方法は考えられますか?

4

6 に答える 6

9
INNER JOIN attribute_values av
    ON av.attribute_definition_id = #statusCode# 
LEFT JOIN attribute_values av2
    ON pe.prodtree_element_id = av.prodtree_element_id

これが問題です。pe と av の間にクロス結合があり、その後にクロス結合への外部結合があります。30分しかかからないのは幸運です:-)

私はあなたがこれを望んでいると思います:

SELECT pe.prodtree_element_id prodID, pe.prodtree_element_name_s, li.line_name, av2.value
FROM prodtree_element pe
LEFT JOIN prodtree_link pl
    ON pe.prodtree_element_id = pl.to_prodtree_node_id
LEFT JOIN line li
    ON pe.line_code = li.line_code
--replacement
LEFT JOIN
attribute_values av 
         ON pe.prodtree_element_id = av.prodtree_element_id AND
         av.attribute_definition_id = #statusCode# 
--end replacement
WHERE pe.prodtree_element_func_type <> 'WIZARD'
    AND pe.prodtree_element_topo_type = 'NODE'
于 2008-12-09T20:05:59.380 に答える
0

最初にお勧めするのは、エンタープライズ マネージャーがインストールされている場合は、エンタープライズ マネージャーの sql オプティマイザー ユーティリティを使用して実行することです。通常、クエリ速度にプラスの影響を与える可能性のあるインデックスなどを提案します。

他に考慮すべきことは、クエリを分割することです。一見すると、指定した値 (またはそのようなもの) に一致する特定の属性を持つすべての製品要素を読み取っているように見えます。私は多分お勧めします:

select * from [bigLongjoin to producttree_element]
where prodtree_element_id
in(
select prodtree_element_id from 
  attribute_values where attribute_definition_id = #statusCode#)

クエリ プランを表示して Enterprise Manager で実行すると、ボトルネックがどこにあるかがわかります。

于 2008-12-09T20:03:57.980 に答える
0

適切な最適化により、数秒で数百万のレコードを検索できます。StingyJack は DDL を知らなくても正しいですが、クエリの最適化は困難です。

ただし、クエリを最適化するときに行うべきことは、実行計画を確認することです。ネストされたループなどは良くありません。また、完全に索引付けされていることも確認してください。問題のテーブルのインデックスについては何も言及していません。インデックスがないと、30 ~ 50k 行の場合、多くの結合で時間がかかる可能性があります。

于 2008-12-09T20:06:29.800 に答える
0

以下をマップできる場合は、すべての ID がインデックスであることも確認してください。

pe.prodtree_element_func_type <> 'WIZARD'
        AND pe.prodtree_element_topo_type = 'NODE'

のようなものになる

pe.prodtree_element_func_type_ID <> 1
            AND pe.prodtree_element_topo_type_ID = 2

完了するまでにより多くの時間がかかる文字列比較を減らすために

于 2008-12-09T20:07:20.330 に答える
0

DDL を知らなければ、テストするのは非常に困難です。30 ~ 50K 行でも数秒しかかかりません。

where 句の順序を変更してみてください。おそらくこれを実装する必要があります

 INNER JOIN attribute_values av
        ON av.attribute_definition_id = #statusCode# 

where句で。

于 2008-12-09T20:01:13.790 に答える
0
SELECT pe.prodtree_element_id prodID, pe.prodtree_element_name_s, li.line_name, av2.value
    FROM prodtree_element pe
    LEFT JOIN prodtree_link pl
        ON (pe.prodtree_element_id = pl.to_prodtree_node_id)
    LEFT JOIN line li
        ON (pe.line_code = li.line_code)
    LEFT JOIN attribute_values av2
        ON (pe.prodtree_element_id IN (SELECT av.prodtree_element_id FROM attribute_values av WHERE av.attribute_definition_id = #statusCode#))
    WHERE pe.prodtree_element_func_type <> 'WIZARD'
        AND pe.prodtree_element_topo_type = 'NODE'

gbnはそれを釘付けにしたと思います。INNER JOIN to attribute_values を特定の値に制限しても、プライマリ テーブルまたはそのリレーションシップにはまったく結合されません。そのため、クエリから結果が得られたとしても、結果が多すぎると思います。

あなたが意図したことと、データがattribute_valuesテーブルにどのようにあるかに応じて、彼のクエリまたは私のクエリの方がおそらく高速です。

于 2008-12-09T20:15:44.757 に答える