是否会按照DTA的建议添加不支持的索引来提高性能?

时间:2013-02-23 14:06:54

标签: sql sql-server performance sql-server-2008 indexing

我在数据库中定义了以下表格

购物表

  • ShopId
  • ShopName
  • 所有者
  • 横幅
  • 标题
  • CityId
  • ShopImageId
  • 有效

城市表

  • CityId
  • CITYNAME
  • CountryId
  • RegionId

国家/地区表

  • CountryId
  • 国家或地区名称
  • RegionId

REGION

  • RegionId
  • RegionName

ShopImages

  • 编号
  • 图像
  • ShopId

这是我的选择查询

SELECT ShopName, Owner, CityName, CountryName,RegionName
FROM Shop S 
INNER JOIN City CT ON CT.CityId=S.CityId
INNER JOIN Country CO ON CO.CountryId=CT.CountryId
INNER JOIN Region R ON CT.RegionId=R.RegionId
LEFT OUTER JOIN ShopImages SI ON S.ShopImageId=SI.Id

WHERE S.Banner like '%restaurant%' OR S.Description like '%restaurant%'
AND S.CityId=10 AND S.Active=1
  

截至目前,城市表有大约3,000,000条记录和商店有   40,000,000 +条记录。

获取记录需要时间。已定义所有聚簇索引(主键)。

  

我正在尝试在DTA(数据库调优顾问)的帮助下进行优化。   它建议我添加以下索引

CREATE NONCLUSTERED INDEX 
  [_dta_index_CITY_9_2098106515__K9_K20_K1_K2] ON [dbo].[CITY] 
(
    [COUNTRYID] ASC,
    [REGIONID] ASC,
    [CITYID] ASC,
    [CITYNAME] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) 
  ON [PRIMARY]

是否值得添加此索引?我可以从DTA中获取所有的建议吗?它还建议增加一些统计数据。

如何更好地改进我的上述查询?

2 个答案:

答案 0 :(得分:2)

在分析索引时很难说DTA是错误的,因为我不知道数据的分布情况,但是我在主键之外添加的第一个索引是SHOP.CityIDSHOP.Active上的(可能是复合的)索引。

如果没有测试,我不能给你任何绝对,但这就是推理。

由于您基本上是在SHOP上进行过滤并且在任何其他表上都没有过滤器,因此查询的繁重工作很可能是在SHOP中过滤50M行。

如果数据库从任何其他表开始加入,则未经过滤的连接将导致针对CITY的3M行,并且从过滤SHOP开始将极有可能导致更少的数量。编译器喜欢“少”,这是有充分理由的。

这是SHOP;

上的过滤器
WHERE S.Banner like '%restaurant%' OR S.Description like '%restaurant%'
  AND S.CityId=10 AND S.Active=1

由于以LIKE为基础的%查询基本上无法使用索引,因此您需要尽可能简单快速地过滤{{1} }。如果你索引那些,其他两个条件将不需要扫描超过使用索引找到的几行而不是扫描 - 可能 - 50M行。

我可以看到索引建议的唯一原因不仅仅是一个小的影响,如果S.CityId=10 AND S.Active=1表有大量的字段,索引将允许数据库从磁盘读取更少的数据到达田野。不是说情况,但只是尝试它肯定会说明。

答案 1 :(得分:1)

在某些情况下,您可能需要重新考虑在主键列上使用聚簇索引。

例如,如果您通常搜索特定城市中的商店(如果示例查询是“典型查询”就是这种情况),那么将Shop聚集在CityId上可能是非常有益的(以便所有商店都在给定的城市组合在一起)