这是我桌子的构造
CREATE TABLE [dbo].[InterfaceMeraAdReport_CAV](
[ID] [int] IDENTITY(1,1) NOT NULL,
[reportID] [nvarchar](100) NOT NULL,
[FromTime] [nvarchar](100) NOT NULL,
[ToTime] [nvarchar](100) NOT NULL,
[Customer] [nvarchar](100) NOT NULL,
[Area] [nvarchar](100) NOT NULL,
[Vendor] [nvarchar](100) NOT NULL,
[SuccessCalls] [nvarchar](100) NOT NULL,
[TotalCalls] [nvarchar](100) NOT NULL,
[TotalMins] [nvarchar](100) NOT NULL,
[ASR] [nvarchar](100) NOT NULL,
[ACD] [nvarchar](100) NOT NULL,
[Fee] [nvarchar](100) NOT NULL,
[Cost] [nvarchar](100) NOT NULL,
[Profix] [nvarchar](100) NOT NULL,
CONSTRAINT [PK_MeraAdvReport_CA] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
和两个最常用的查询是这种形式: 一个
select Customer,vendor,SUM(cast(SuccessCalls as int)) as successCalls,
SUM(cast(TotalCalls as int)) as TotalCalls,
SUM(cast(TotalMins as decimal(18,2))) as TotalMins,
case when SUM(cast(TotalCalls as decimal(18,2))) = 0 then 0.0 else (SUM(cast(SuccessCalls as decimal(18,2))) / SUM(cast(TotalCalls as decimal(18,2)))) end as ASR,
case when SUM(cast(SuccessCalls as decimal(18,2))) = 0 then 0.0 else (SUM(cast(TotalMins as decimal(18,2))) / SUM(cast(SuccessCalls as decimal(18,2)))) end as ACD,
SUM(cast(Profix as decimal(18,2))) as profix
from InterfaceMeraAdReport_CAV
where FromTime >= '20140128020000' and ToTime <= '20140128030000'
and Customer= '01.2136' and Area in ('62817','62818','62819','62859','62877','62878','62879')
group by Customer,Vendor
两个
select Customer,SUM(cast(SuccessCalls as int)) as successCalls,
SUM(cast(TotalCalls as int)) as TotalCalls,
SUM(cast(TotalMins as decimal(18,2))) as TotalMins,
case when SUM(cast(TotalCalls as decimal(18,2))) = 0 then 0.0 else (SUM(cast(SuccessCalls as decimal(18,2))) / SUM(cast(TotalCalls as decimal(18,2)))) end as ASR,
case when SUM(cast(SuccessCalls as decimal(18,2))) = 0 then 0.0 else (SUM(cast(TotalMins as decimal(18,2))) / SUM(cast(SuccessCalls as decimal(18,2)))) end as ACD
from InterfaceMeraAdReport_CAV
where FromTime >= @timeFrom and ToTime <= @timeTo
and Customer= @customer and Area in ('62817','62818','62819','62859','62877','62878','62879')
group by Customer
这个表每天增加大约300000条记录,所以现在上面的查询变得越来越慢,
我想创建索引以提高速度,但我不知道最有效的方法,任何人都可以告诉我哪些列将是最佳索引列
答案 0 :(得分:0)
根据您的数据,您可能会发现FromTime > 20140128020000
,尤其是ToTime < 20140128030000
可能没有足够的选择性来保证单独使用这些列中的任何一个索引。
因此,您只需要Customer
和Area
- 您需要了解表格中这些列的数据分布情况。
假设Customer
具有高选择性,并假设客户与区域高度相关(即客户通常只来自一个区域),那么请尝试尽可能缩小您的索引,例如:
CREATE INDEX IX_MyIndex ON InterfaceMeraAdReport_CAV(Customer)
如果客户与区域无关,或者客户本身不具有选择性:
CREATE INDEX IX_MyIndex ON InterfaceMeraAdReport_CAV(Customer, Area)
或者,如果Area的选择性高于客户:
CREATE INDEX IX_MyIndex ON InterfaceMeraAdReport_CAV(Area, Customer)
或者如果结果是报告仅针对最近的数据运行并且存在大量遗留数据,那么FromTime
可能是有选择性的:
CREATE INDEX IX_MyIndex ON InterfaceMeraAdReport_CAV(FromTime, Customer)
等。即,您需要了解您的数据才能对索引做出决定。
由于您只获取了select中的6列,因此包含覆盖索引也是有意义的。
CREATE INDEX IX_MyIndex ON InterfaceMeraAdReport_CAV(Customer, Area)
INCLUDE (Vendor, SuccessCalls, TotalCalls, TotalMins, Profix);
或者,如果这两个查询是针对此表的仅重要查询,那么您还应考虑根据这些查询选择CLUSTERED
索引,例如优化最少的页面读取。 <{1}},Customer
和可能Area
可能最适合。
(如果你把它作为聚集索引,显然你不需要覆盖索引。)