私はそれに1,941,092行のデータベースと、クラスタ化された列ストアのインデックスを持っています。私は先日それを照会するときに奇妙な振る舞いに気付き、説明を求めていたので、問題を特定するためにいくつかの質問を書いた。なぜselect文でnullパラメータをチェックすると、クエリの実行が非常に遅くなりますか?
クエリA
DECLARE @loannumber INT = 2222222;
SELECT
*
FROM
MASDATA_CURRENT.BDE.LOAN
WHERE
@loanNumber IS NULL
OR LOAN_NUMBER = @loanNumber;
クエリB
DECLARE @loannumber INT = 2222222;
SELECT
*
FROM
MASDATA_CURRENT.BDE.LOAN
WHERE
LOAN_NUMBER = @loanNumber;
両方のクエリが同じ結果セットを生成します。クエリAの経過時間は1分39秒です。クエリーBの経過時間は11秒です。私が知る限り、ヌルパラメータをチェックしないクエリBは、87%高速に実行されます。キャッシングはしていません -
Statistic | Query A | Query B |
-------------------------|---------|---------|
Cache Plan Size | 224 KB | 432 KB |
Degree of Parallellism | 1 | 8 |
Estimated Operator Cost | 0 (0%) | 0 (0 %) |
Estimated Subtree Cost | 22.103 | 6.32266 |
Estimated Number of Rows | 660449 | 1.00017 |
を繰り返し、同じ結果を示しているバッチを実行すると次のように選択のための
Query A | Query B
-----------------------------------|-----------------------------------
Select | Select
Cost: 0% | Cost: 0%
-----------------------------------|-----------------------------------
Filter | Parallelism
Cost: 6% | (Gather Streams)
| Cost: 1%
-----------------------------------|-----------------------------------
Columnstore Index Scan (Clustered) | Columnstore Index Scan (Clustered)
Cost: 94% | Cost: 99%
統計は以下のとおりです。次のように
クエリの実行計画があります結果に影響を及ぼすように見える。
質問
nullパラメータは、このような大幅に異なる結果を生成するために、なぜチェックするのですか?
私はクエリを書く別の方法を探していないことに注意してください。私はなぜこれが起こるのかについての説明を探しています。
クエリを実行する前にバッファキャッシュとプランキャッシュをクリアしました –
あなたのケースについてはわかりませんが、クエリヒントを追加することで大幅なスピードアップを達成しました。このページを参照してください。多くの種類があります:https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query –
多くの行にNULL値がありますかそのフィールド?統計に基づいて、約半分の行がNULLであるように見えます。 –