我有一個包含1,941,092行的數據庫和一個聚集列存儲索引。我在前些天查詢時注意到一些奇怪的行爲,並想要解釋,所以我寫了一些查詢來隔離問題。爲什麼在select語句中檢查null參數會導致查詢執行速度太慢?
查詢
DECLARE @loannumber INT = 2222222;
SELECT
*
FROM
MASDATA_CURRENT.BDE.LOAN
WHERE
@loanNumber IS NULL
OR LOAN_NUMBER = @loanNumber;
查詢乙
DECLARE @loannumber INT = 2222222;
SELECT
*
FROM
MASDATA_CURRENT.BDE.LOAN
WHERE
LOAN_NUMBER = @loanNumber;
兩個查詢產生相同的結果集。查詢A的經過時間爲1分39秒;查詢B的經過時間是11秒。從我所知道的情況來看,查詢B不檢查null參數,執行速度提高了87%。
的查詢執行計劃如下:在
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%
的選擇統計如下:
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 |
執行批次一再顯示了同樣的結果 - 緩存不似乎會影響結果。
問題
爲什麼一個空參數檢查產生如此截然不同的結果?
請注意,我沒有尋找替代方法來編寫查詢。我正在尋找解釋爲什麼會發生這種情況。
您是否在運行這兩個查詢之前清除了緩衝區高速緩存和計劃高速緩存 –
我不確定您的情況,但在過去,我有通過添加查詢提示實現了顯着的加速。看到這個頁面,有很多種:https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query –
你的很多行有一個NULL值那個領域?根據統計數據,它看起來像大約一半的行是NULL。 –