我需要调整查询以使其运行得更快。目前,我正在使用案例何时总结价值我们如何调整它来解决性能问题。
注释表包含120列,包含1000万条记录。
目前的查询是:
select week ,nullif(Sum(Convert(Numeric(18,2),Amt)),0) [Amt] ,
nullif((case when (Desc<>'FF')then Sum(Convert(Numeric(18,2),Amt)) else 0 end ),0) [Amt2]
from Table1 group by Week,Desc
表格1:
╔════════╦═══════╦════════╗
║ Week ║ Desc ║ Amt ║
╠════════╬═══════╬════════╬
║ 1 ║ FF ║ 25.00 ║
║ 1 ║ ss ║ 55.00 ║
║ 2 ║ ss ║ 78.00 ║
║ 2 ║ FF ║ 99.00 ║
║ 3 ║ ss ║ 54.00 ║
║ 4 ║ FF ║ 58.00 ║
║ 5 ║ FF ║ 55.00 ║
║ 5 ║ ss ║ 55.00 ║
║ 1 ║ ss ║ 77.00 ║
╚════════╩═══════╩════════╝
CREATE TABLE [dbo].[Table] ([Client_Billing_Id] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
[Weekday] [varchar](10) NULL,
[Description] [varchar](1500) NULL,
[NetAmount] [varchar](100) NULL )
CREATE NONCLUSTERED INDEX [Description] ON [dbo].[Table] ( [Description] ASC )
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
问题是你的专栏NetAmount
。您将数值存储为字符串,因此SQL服务器正在对可能的值进行求和。
此外,列Weekday
上没有索引,这意味着服务器在对任何内容进行分组之前扫描整个表。
接下来,你的专栏Description
。为什么它是varchar(1500)
?从你发布的只清楚只存储2个字符,那么...的其他1498个字符是什么?
我会做以下事情
NetAmount
列更改为decimal
(可能基于您的查询(18,2)
)。Description
列更改为char(2)
,因为您只使用2个字符。其他1498个字符的空间完全是浪费int
。它显然不是varchar,这意味着订购是正确的。平日不应该在1, 10, 12, 13...19, 2, 20, 21,...3, 30, 31, 4, 5, 6, 7...
的顺序[Weekday]
和[Description]
以及INCLUDE
列NetAmount
上添加索引。这导致类似于:
ALTER TABLE dbo.[Table] ALTER COLUMN NetAmount decimal(18,2);
ALTER TABLE dbo.[Table] ALTER COLUMN [Description] char(2);
ALTER TABLE dbo.[Table] ALTER COLUMN [Weekday] int;
CREATE INDEX Week_Desc_IX ON dbo.[Table] ([Weekday] ASC, [Description] ASC) INCLUDE ([NetAmount]);
然后,您的查询将变为:
SELECT [WeekDay],
CASE [Description] WHEN 'FF' THEN [Description] ELSE 'SS' END AS [Description],
NULLIF(SUM(NetAmount),0) AS [Amt],
NULLIF(SUM(CASE [Description] WHEN 'FF' THEN Amt END),0) AS [Amt2]
FROM [Table]
GROUP BY [Weekday],
CASE [Description] WHEN 'FF' THEN [Description] ELSE 'SS' END;
这应该表现得更好。