簡體   English   中英

基於WHERE子句的SQL性能

[英]SQL performance based on the WHERE clause

我試圖重用查詢,而不是創建多個方案。 基本上,我從一張大桌子上得到一個COUNT。

問題是:如果長期使用,我是否會失去性能?

SELECT COUNT(id) FROM [Documents] WHERE UploadDate > '1900/1/1' AND UploadDate < GETDATE()

而不是簡單

SELECT COUNT(id) FROM [Documents]

基本上,這兩個查詢將返回相同的內容,因為在這種情況下,我想返回所有記錄。 但是在其他情況下,日期對將使用不同的參數。

如果要先計算所有事物 ,然后計算滿足條件的事物:

SELECT COUNT(id) as total_cnt,
       SUM(CASE WHEN UploadDate > '1900-01-01' AND UploadDate < GETDATE()
                THEN 1 ELSE 0
           END) as specific_cnt
FROM [Documents] d;

如果由於參數嗅探而擔心根據查詢中指定的范圍值來改變性能,則可以在查詢末尾添加OPTION (RECOMPILE)

SELECT COUNT(id) 
FROM [Documents] 
WHERE UploadDate > '1900/1/1' AND UploadDate < GETDATE()
OPTION (RECOMIPLE)

如果您決定從'2011/1/1'開始進行檢查,這將確保您新生成的計划是最佳的選擇,此時優化器可以針對該日期范圍自行提出該日期范圍。 。

如果您希望基於某些參數進行計數,那么我認為如果在UploadDate定義了索引, UploadDate會有明顯的區別。 如果使用的是存儲過程,則可能如下所示:

CREATE PROCEDURE dbo.GetCount
(
   @FromDate DATETIME2 = '1900-01-01',
   @ToDate DATETIME2 = '9999-12-31',
   -- other filters may come here
)
AS
BEGIN
   SELECT COUNT(id) 
   FROM [Documents] 
   WHERE UploadDate > @FromDate AND @ToDate < @ToDate
END
GO

-- get all
EXEC dbo.GetCount
-- get from date
EXEC dbo.GetCount @FromDate = '2015-03-01'
-- to date
EXEC dbo.GetCount @ToDate = '2016-03-01'
-- both
EXEC dbo.GetCount @FromDate = '2015-03-01', @ToDate = '2016-03-01'

您還可以嘗試通過創建動態SQL來獲取運行的最低SQL

CREATE PROCEDURE dbo.GetCount
(
   @FromDate DATETIME2 = NULL,
   @ToDate DATETIME2 = NULL
   -- other filters may come here
)
AS
BEGIN
   DECLARE @SQL NVARCHAR(4000) = N'
       SELECT COUNT(id) FROM [Documents]
       WHERE 1 = 1 
   '
   IF (@FromDate IS NOT NULL) @SQL = @SQL + ' UploadDate > @FromDate'
   IF (@ToDate IS NOT NULL) @SQL = @SQL + ' UploadDate > @ToDate'

   EXECUTE sp_executesql @SQL, '@FromDate DATETIME2, @ToDate DATETIME2', @FromDate, @ToDate
END

這提供了向左和/或向右打開間隔的靈活性。

如果要從應用程序層動態生成查詢 (例如LINQ2SQL),最好的選擇是根據您的參數生成查詢 這將導致最短和最快的查詢:

var query = DbContext.Documents;
if (fromDate.HasValue) query = query.Where(UploadDate > fromDate.Value);
if (toDate.HasValue) query = query.Where(UploadDate < toDate.Value);
int count = query.Count();

最后兩個解決方案還允許輕松添加新的過濾器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM