作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用基于另一个答案的以下 SQL 代码。但是,当包含大量 in 子句时,获取总数需要太长时间。如果我删除总计数,则查询时间不到 1 秒。有没有更有效的方法来获得总行数?我看到的答案基于 2013 SQL 查询。
DECLARE
@PageSize INT = 10,
@PageNum INT = 1;
WITH TempResult AS(
SELECT ID, Name
FROM Table
Where ID in ( 1 ,2 3, 4, 5, 6, 7, 8, 9 ,10)
), TempCount AS (
SELECT COUNT(*) AS MaxRows FROM TempResult
)
SELECT *
FROM TempResult,
TempCount <----- this is what is slow. Removing this and the query is super fast
ORDER BY TempResult.Name
OFFSET (@PageNum-1)*@PageSize ROWS
FETCH NEXT @PageSize ROWS ONLY
最佳答案
性能相关问题的第一步将是分析您的表/索引结构,并审查查询计划。你还没有提供这些信息,所以我要自己编造,然后从那里开始。
我将假设您有一个堆,大约有 10M 行(对我来说是 12,872,738):
DECLARE @MaxRowCount bigint = 10000000,
@Offset bigint = 0;
DROP TABLE IF EXISTS #ExampleTable;
CREATE TABLE #ExampleTable
(
ID bigint NOT NULL,
Name varchar(50) COLLATE DATABASE_DEFAULT NOT NULL
);
WHILE @Offset < @MaxRowCount
BEGIN
INSERT INTO #ExampleTable
( ID, Name )
SELECT ROW_NUMBER() OVER ( ORDER BY ( SELECT NULL )),
ROW_NUMBER() OVER ( ORDER BY ( SELECT NULL ))
FROM master.dbo.spt_values SV
CROSS APPLY master.dbo.spt_values SV2;
SET @Offset = @Offset + ROWCOUNT_BIG();
END;
#ExampleTable
提供的查询,大约需要 4 秒,并给我这个查询计划:
IN
中提供大量项目列表(从 1 到 5000 的 5000 个项目)。编译计划花了 4 秒钟:
IN
列出临时表或表变量。 OPTION( USE HINT( 'FORCE_DEFAULT_CARDINALITY_ESTIMATION' ) )
得到第一个。对于第二个,向 CCI 添加一个连接(不需要返回数据):
LEFT OUTER JOIN dbo.EmptyCciForRowstoreBatchmode ON 1 = 0
- 这使 SQL Server 能够选择批处理模式优化。这些建议假定 SQL Server 版本足够新。
CREATE TABLE dbo.EmptyCciForRowstoreBatchmode
(
__zzDoNotUse int NULL,
INDEX CCI CLUSTERED COLUMNSTORE
);
WITH TempResult AS
(
SELECT ID,
Name,
COUNT( * ) OVER ( ) MaxRows
FROM #ExampleTable
WHERE ID IN ( <<really long LIST>> )
)
SELECT TempResult.ID,
TempResult.Name,
TempResult.MaxRows
FROM TempResult
LEFT OUTER JOIN dbo.EmptyCciForRowstoreBatchmode ON 1 = 0
ORDER BY TempResult.Name OFFSET ( @PageNum - 1 ) * @PageSize ROWS FETCH NEXT @PageSize ROWS ONLY
OPTION( USE HINT( 'FORCE_DEFAULT_CARDINALITY_ESTIMATION' ) );
关于使用 IN 子句时 SQL Offset 总行数变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58714684/
我是一名优秀的程序员,十分优秀!