在不使用案例时如何对值进行求和

问题描述 投票:0回答:1

我需要调整查询以使其运行得更快。目前,我正在使用案例何时总结价值我们如何调整它来解决性能问题。

注释表包含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]
sql sql-server database
1个回答
0
投票

问题是你的专栏NetAmount。您将数值存储为字符串,因此SQL服务器正在对可能的值进行求和。

此外,列Weekday上没有索引,这意味着服务器在对任何内容进行分组之前扫描整个表。

接下来,你的专栏Description。为什么它是varchar(1500)?从你发布的只清楚只存储2个字符,那么...的其他1498个字符是什么?

我会做以下事情

  1. 将您的NetAmount列更改为decimal(可能基于您的查询(18,2))。
  2. Description列更改为char(2),因为您只使用2个字符。其他1498个字符的空间完全是浪费
  3. 将工作日更改为int。它显然不是varchar,这意味着订购是正确的。平日不应该在1, 10, 12, 13...19, 2, 20, 21,...3, 30, 31, 4, 5, 6, 7...的顺序
  4. [Weekday][Description]以及INCLUDENetAmount上添加索引。

这导致类似于:

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;

这应该表现得更好。

© www.soinside.com 2019 - 2024. All rights reserved.