我在使用数百万行表时遇到了一些严重的性能问题,我觉得我应该能够相当快地获得结果。这是我所拥有的,我如何查询它,以及它需要多长时间:
我正在运行 SQL Server 2008 Standard,因此分区目前不是一个选项
我正在尝试汇总过去 30 天内特定帐户的所有库存的所有视图。
所有视图都存储在下表中:
创建表 [dbo].[LogInvSearches_Daily](
[ID] [bigint] IDENTITY(1,1) 非空,
[Inv_ID] [int] 非空,
[Site_ID] [int] 非空,
[LogCount] [int] 非空,
[LogDay] [smalldatetime] 非空,
约束 [PK_LogInvSearches_Daily] 主键集群
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) 开 [主要]
该表有 132,000,000 条记录,超过 4 个演出。
表中 10 行的样本:
ID Inv_ID Site_ID LogCount LogDay -------- ----------- ----------- -------- --- ------------ 1 486752 48 14 2009-07-21 00:00:00 2 119314 51 16 2009-07-21 00:00:00 3 313678 48 25 2009-07-21 00:00:00 4 298863 0 1 2009-07-21 00:00:00 5 119996 0 2 2009-07-21 00:00:00 6 463777 534 7 2009-07-21 00:00:00 7 339976 503 2 2009-07-21 00:00:00 8 333501 570 4 2009-07-21 00:00:00 9 453955 0 12 2009-07-21 00:00:00 10 443291 0 4 2009-07-21 00:00:00 (10 行受影响)
- 我在 LogInvSearches_Daily 上有以下索引:
/****** 对象:索引 [IX_LogInvSearches_Daily_LogDay] 脚本日期:05/12/2010 11:08:22 ******/
在 [dbo] 上创建非聚类索引 [IX_LogInvSearches_Daily_LogDay]。[LogInvSearches_Daily]
(
[日志日] ASC
)
包括([Inv_ID],
[LogCount]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
- 我只需要从特定帐户 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] < [Expr1012]) 已订购)
|--索引查找(OBJECT:([propertyControlCenter].[dbo].[Inventory].[IX_Inventory_Acct_ID]), SEEK:([propertyControlCenter].[dbo].[Inventory].[Acct_ID]=(18731) AND [ propertyControlCenter].[dbo].[Inventory].[Inv_ID]=[LOA
(13 行受影响)
我尝试使用 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] < [Expr1009]) 已订购)
|--Index Seek(OBJECT:([propertyControlCenter].[dbo].[Inventory].[IX_Inventory_Acct_ID] AS [I]), SEEK:([I].[Acct_ID]=(18731) AND [I].[ Inv_ID]=[LOALogs].[dbo].[LogInvSearches_Daily].[Inv_ID] as [D].[Inv_ID])
(受影响的 8 行)
(1 行受影响)
因此,鉴于我在执行计划中获得了良好的 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] < [Expr1011]) 已订购)
|--Index Seek(OBJECT:([propertyControlCenter].[dbo].[Inventory].[IX_Inventory_Acct_ID]), SEEK:([propertyControlCenter].[dbo].[Inventory].[Acct_ID]=(18731) AND [ propertyControlCenter].[dbo].[Inventory].[Inv_ID]=[LOALogs].[dbo].[LogInvS
(9 行受影响)
谢谢,
担