简体   繁体   English

对此表,有一个最常用的查询,如何创建良好的索引以提高速度

[英]To this table , there is a mostly used query , How to create good index to improve speed

this is my table 's construct 这是我表的构造

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]

and two mostly used query is this form : one 两种最常用的查询是这种形式:

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

two

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

this table increase about 300000 records every day , so now above query become more and more slower , 该表每天增加约30万条记录,因此现在上面的查询变得越来越慢,

i want to create index to improve speed , but i do not know the most effective way , can anybody tell me which columns will be the best index column 我想创建索引以提高速度,但是我不知道最有效的方法,有人可以告诉我哪些列将是最佳索引列

Depending on your data, you might find that FromTime > 20140128020000 and especially ToTime < 20140128030000 might NOT be selective enough to warrant an index on either of these columns alone. 根据您的数据,您可能会发现FromTime > 20140128020000 ,尤其是ToTime < 20140128030000可能没有足够的选择性来保证仅在这两个列中的任何一个上创建索引。

So this leaves you with Customer and Area - again you would need to understand the distribution of data in your table for these columns. 因此,这将使您CustomerArea -同样,您将需要了解表中这些列的数据分布。

Assuming high selectivity on Customer , and assuming that Customer IS highly correlated to Area (ie Customer is typically only from one area), then try keep your index as narrow as possible, eg: 假设对Customer具有很高的选择性,并假设Customer与Area高度相关(即,Customer通常仅来自一个区域),则尝试使索引尽可能窄,例如:

CREATE INDEX IX_MyIndex ON InterfaceMeraAdReport_CAV(Customer)

If Customer is NOT correlated to area, or if Customer by itself is not selective: 如果客户与区域不相关,或者客户本身不是选择性的:

CREATE INDEX IX_MyIndex ON InterfaceMeraAdReport_CAV(Customer, Area)

Or if Area has better selectivity than customer: 或者,如果Area具有比客户更好的选择性:

CREATE INDEX IX_MyIndex ON InterfaceMeraAdReport_CAV(Area, Customer)

Or if it turns out that the report is run for recent data only and there is a large amount of legacy data, then FromTime could be selective: 或者,如果事实证明该报告仅针对最新数据运行,并且有大量旧数据,则FromTime可能是有选择的:

CREATE INDEX IX_MyIndex ON InterfaceMeraAdReport_CAV(FromTime, Customer)

etc. ie You will need to know your data in order to make decisions on indexes. 等等。例如,您将需要了解您的数据才能做出有关索引的决策。

Since you fetch only 6 of the columns in the select, it may also make sense to include a covering index. 由于仅获取选择中的6列,因此包含覆盖索引也很有意义。

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

Alternatively, if these 2 queries are the only significant queries against this table, then you should also consider choosing the CLUSTERED index based on these queries, eg optimize for fewest page reads. 或者,如果这两个查询是针对该表的唯一重要查询,那么您还应该考虑基于这些查询选择CLUSTERED索引,例如针对最少的页面读取进行优化。 Customer , Area and possibly FromTime again will probably be most suited. CustomerArea以及可能的FromTime可能最适合。

(Obviously you won't need a covering index if this if you make this the clustered index). (显然,如果将其设为聚集索引,则不需要覆盖索引)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM