2

17 個の結合 (内側と左右の外側の両方) とサブクエリを含む複雑なクエリに基づくビューを使用します。すべてのビュー行が約 5 秒で表示されます。

SELECT * FROM a_view;

ビュー列の 1 つに BIT 型があります。そして、それを 1 と比較してビューの行をフィルタリングすると、クエリは約 5 秒で再び機能します。

SELECT * FROM a_view WHERE c = 1;

しかし、この BIT 列を 0 と比較すると、クエリは約 50 秒 (10 倍遅く) 動作します。

SELECT * FROM a_view WHERE c = 0;

同じ結果行を返すこのクエリは、約 10 秒間期待どおりに機能します。

SELECT * FROM a_view 
EXCEPT
SELECT * FROM a_view WHERE c = 1;

では、なぜ 0 または 'FALSE' との比較に時間がかかるのでしょうか。アイデアをお願いします。

この BIT フィールドでのソートは高速です。他の列によるフィルタリングも高速です。

4

5 に答える 5

1

SQL Server SQL エンジンは、ビューに記述した SQL ステートメント内にビューの SQL クエリ全体を配置し、それを最適化しようとします。

これにより、c=0 の場合、使用されるテーブルの統計が、c=1 の場合よりもその述語に一致する行がはるかに多いことが示される状況につながる可能性があります。たとえば、c=1 の場合、結合の中心である c フィールドを含むテーブルは、5 つの一致する行のみを返す可能性があります。これは、テーブルが 100 万行を返す場合 (たとえば、 c=0 の場合)。

したがって、両方の実行計画を調べてください。また、両方のサーバー プロファイラーの結果を調べます。c=0 の場合、c=1 よりもはるかに多くの読み取りがあり、c=1 よりもはるかに多くの結果が返される可能性があります。すべての行を返すには時間がかかる場合があるため、これもクエリが遅くなる理由である可能性があります。

于 2009-01-22T10:59:17.307 に答える
1

通常、結合を含むクエリを実行する方法は複数あります。最新のすべての RDBMS は、さまざまな結合プランを検索して、それぞれのコスト (CPU およびディスク アクセス時間) を見積もり、最適なプランを探します。

問題は、クエリに結合を追加するたびに、可能なプランの数が増加する数で乗算され、結合の数が増えるにつれて、考慮すべきプランの数が 2 倍 (指数関数的ではなく) 増加することです。そのため、DB はどこかで検索を制限する必要があります。つまり、多くの結合を含むクエリでは、必然的に次善の計画が選択されます。

参考までに、PostgreSQL はデフォルトで 12 回の結合後にすべての可能なプランの評価を停止します。SQL Server にも同様の制限があります。17 個の結合を評価するには (2 * 13) * (2 * 14) * (2 * 15) * (2 * 16) * (2 * 17) 倍の時間がかかります。これまでに存在したか、または今後も存在します

また、DB は、列内の個別の値の数や列内の最も一般的な 10 個の値のリストなど、大まかな統計に基づいてコストを見積もっていることも考慮する必要があります。これはすべて、結合の数が増えるにつれて、最適な (または合理的な) 結合戦略を選択する可能性が大幅に低下するという事実につながります。

17 のテーブルを結合する必要があるのはなぜですか? DB スキーマを単純化する方法はありませんか?

于 2009-01-22T11:03:35.830 に答える