我正在尝试重用查询,而不是创建多个方案。基本上我从大桌子上得到一个COUNT。
问题是:如果我使用
,我将在长期失去表现SELECT COUNT(id) FROM [Documents] WHERE UploadDate > '1900/1/1' AND UploadDate < GETDATE()
而不是简单的
SELECT COUNT(id) FROM [Documents]
基本上2个查询会返回相同的内容,因为我想在这种情况下返回所有记录。但在某些其他情况下,日期对将使用不同的参数。
答案 0 :(得分:0)
如果您想计算所有内容,然后计算符合条件的内容:
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;
答案 1 :(得分:0)
如果您担心根据您在查询中指定的范围值而改变性能,由于参数嗅探,您可以在查询结尾处添加OPTION (RECOMPILE)
。
SELECT COUNT(id)
FROM [Documents]
WHERE UploadDate > '1900/1/1' AND UploadDate < GETDATE()
OPTION (RECOMIPLE)
如果您决定从'2011/1/1'
开始检查,那么这将确保您新生成的计划是Optimizer可以在该时刻自行提出的最佳方案。示例
答案 2 :(得分:0)
如果您想根据某些参数进行计数,如果您在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();
最后两个解决方案还允许轻松添加新过滤器。