【问题标题】:To this table , there is a mostly used query , How to create good index to improve speed对这张表,有一个最常用的查询,如何创建好的索引来提高速度
【发布时间】:2014-01-28 03:06:36
【问题描述】:

这是我的桌子的构造

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条记录,所以现在上面的查询变得越来越慢,

我想创建索引来提高速度,但我不知道最有效的方法,谁能告诉我哪些列是最好的索引列

【问题讨论】:

    标签: sql-server performance indexing


    【解决方案1】:

    根据您的数据,您可能会发现FromTime &gt; 20140128020000 尤其是ToTime &lt; 20140128030000 的选择性可能不足以保证仅在其中任一列上建立索引。

    所以这给您留下了CustomerArea - 您需要再次了解表中这些列的数据分布。

    假设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)
    

    等等。即,您需要了解您的数据才能对索引做出决策。

    由于您在选择中仅获取 6 个列,因此包含覆盖索引也可能有意义。

    CREATE INDEX IX_MyIndex ON InterfaceMeraAdReport_CAV(Customer, Area) 
    INCLUDE (Vendor, SuccessCalls, TotalCalls, TotalMins, Profix);
    

    或者,如果这 2 个查询是针对此表的唯一 个重要查询,那么您还应该考虑根据这些查询选择 CLUSTERED 索引,例如优化最少的页面读取。 CustomerAreaFromTime 可能是最合适的。

    (如果你把它设为聚集索引,显然你不需要覆盖索引)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-14
      • 1970-01-01
      • 1970-01-01
      • 2019-09-27
      相关资源
      最近更新 更多