【发布时间】:2010-05-12 16:26:55
【问题描述】:
我在处理数百万行表时遇到了一些严重的性能问题,我觉得我应该能够相当快地获得结果。以下是我所拥有的、我如何查询它以及需要多长时间:
我运行的是 SQL Server 2008 Standard,因此分区目前不是一个选项
我正在尝试汇总过去 30 天内特定帐户的所有广告资源的所有视图。
所有视图都存储在下表中:
此表有 132,000,000 条记录,超过 4 个演出。
表格中的 10 行样本:
- 我在 LogInvSearches_Daily 上有以下索引:
- 我只需要从特定帐户 ID 的库存中提取库存。我也有关于库存的索引。
我正在使用以下查询来聚合数据并为我提供前 5 条记录。此查询目前需要 24 秒才能返回 5 行:
文本 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------ 选择前 5 名 Sum(LogCount) AS 浏览量 , DENSE_RANK() OVER(ORDER BY Sum(LogCount) DESC, Inv_ID DESC) AS Rank , Inv_ID FROM LogInvSearches_Daily D (NOLOCK) 在哪里 LogDay > DateAdd(d, -30, getdate()) 并且存在( 从 propertyControlCenter.dbo.Inventory (NOLOCK) 中选择 NULL,其中 Acct_ID = 18731 AND Inv_ID = D.Inv_ID ) 按 Inv_ID 分组 (1 行受影响) 文本 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------ |--顶部(顶部表达式:((5))) |--序列项目(DEFINE:([Expr1007]=dense_rank)) |--细分市场 |--细分市场 |--排序(排序方式:([Expr1006] DESC,[D].[Inv_ID] DESC)) |--Stream Aggregate(GROUP BY:([D].[Inv_ID]) DEFINE:([Expr1006]=SUM([LOALogs].[dbo].[LogInvSearches_Daily].[LogCount] as [D].[LogCount] ))) |--排序(ORDER BY:([D].[Inv_ID] ASC)) |--嵌套循环(内连接,外引用:([D].[Inv_ID])) |--嵌套循环(内连接,外引用:([Expr1011],[Expr1012],[Expr1010])) | |--计算标量(DEFINE:(([Expr1011],[Expr1012],[Expr1010])=GetRangeWithMismatchedTypes(dateadd(day,(-30),getdate()),NULL,(6)))) | | |--恒定扫描 | |--Index Seek(OBJECT:([LOALogs].[dbo].[LogInvSearches_Daily].[IX_LogInvSearches_Daily_LogDay] AS [D]), SEEK:([D].[LogDay] > [Expr1011] AND [D].[ LogDay]我尝试使用 CTE 先获取行并聚合它们,但这并没有更快地运行,并且给了我基本相同的执行计划。
(1 行受影响) 文本 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------ --SET SHOWPLAN_TEXT ON; 使用 getSearches 作为 ( 选择 日志计数 -- , DENSE_RANK() OVER(ORDER BY Sum(LogCount) DESC, Inv_ID DESC) AS Rank , D.Inv_ID FROM LogInvSearches_Daily D (NOLOCK) INNER JOIN propertyControlCenter.dbo.Inventory I (NOLOCK) ON Acct_ID = 18731 AND I.Inv_ID = D.Inv_ID 在哪里 LogDay > DateAdd(d, -30, getdate()) -- 按 Inv_ID 分组 ) SELECT Sum(LogCount) AS 视图,Inv_ID 来自 getSearches 按 Inv_ID 分组 (1 行受影响) 文本 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------- |--Stream Aggregate(GROUP BY:([D].[Inv_ID]) DEFINE:([Expr1004]=SUM([LOALogs].[dbo].[LogInvSearches_Daily].[LogCount] as [D].[LogCount] ))) |--排序(ORDER BY:([D].[Inv_ID] ASC)) |--嵌套循环(内连接,外引用:([D].[Inv_ID])) |--嵌套循环(内连接,外引用:([Expr1008],[Expr1009],[Expr1007])) | |--计算标量(DEFINE:(([Expr1008],[Expr1009],[Expr1007])=GetRangeWithMismatchedTypes(dateadd(day,(-30),getdate()),NULL,(6)))) | | |--恒定扫描 | |--Index Seek(OBJECT:([LOALogs].[dbo].[LogInvSearches_Daily].[IX_LogInvSearches_Daily_LogDay] AS [D]), SEEK:([D].[LogDay] > [Expr1008] AND [D].[ LogDay]鉴于我的执行计划中的 Index Seeks 很好,我可以做些什么来让它运行得更快?
更新:
这是没有 DENSE_RANK() 的相同查询运行,它需要完全相同的 24 秒运行,并给我相同的基本查询计划:
文本 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------ --SET SHOWPLAN_TEXT ON 选择前 5 名 Sum(LogCount) AS 浏览量 , Inv_ID FROM LogInvSearches_Daily D (NOLOCK) 在哪里 LogDay > DateAdd(d, -30, getdate()) 并且存在( 从 propertyControlCenter.dbo.Inventory (NOLOCK) 中选择 NULL,其中 Acct_ID = 18731 AND Inv_ID = D.Inv_ID ) 按 Inv_ID 分组 按视图排序,Inv_ID (1 行受影响) 文本 -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------ |--排序(前 5 名,排序方式:([Expr1006] ASC,[D].[Inv_ID] ASC)) |--Stream Aggregate(GROUP BY:([D].[Inv_ID]) DEFINE:([Expr1006]=SUM([LOALogs].[dbo].[LogInvSearches_Daily].[LogCount] as [D].[LogCount] ))) |--排序(ORDER BY:([D].[Inv_ID] ASC)) |--嵌套循环(内连接,外引用:([D].[Inv_ID])) |--嵌套循环(内连接,外引用:([Expr1010],[Expr1011],[Expr1009])) | |--计算标量(DEFINE:(([Expr1010],[Expr1011],[Expr1009])=GetRangeWithMismatchedTypes(dateadd(day,(-30),getdate()),NULL,(6)))) | | |--恒定扫描 | |--Index Seek(OBJECT:([LOALogs].[dbo].[LogInvSearches_Daily].[IX_LogInvSearches_Daily_LogDay] AS [D]), SEEK:([D].[LogDay] > [Expr1010] AND [D].[ LogDay]谢谢,
丹
【问题讨论】:
-
您能否提供一个您希望看到的输出示例?目前尚不清楚为什么您需要 DENSE_RANK 。
-
我只需要前 5 名。刚刚发布了一个更新,显示有或没有 DENSE_RANK() 的性能完全相同。
标签: sql tsql sql-server-2008 aggregate large-data-volumes