我在数据库中定义了以下表
商店表
城市桌
国家表
区域
ShopImages
这是我的选择查询
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条记录&商店有4,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的所有建议吗?它还建议增加一些统计数据。
怎样才能更好地改进我的上述查询?
发布于 2013-02-23 14:34:16
很难说DTA在分析索引时是错误的,因为我不知道数据分布,而且它确实知道,但是我在主键之外添加的第一个索引是SHOP.CityID和SHOP.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查询从%开始根本不能使用索引,所以您希望S.CityId=10 AND S.Active=1尽可能地进行狭义和快速的筛选。如果对这些数据进行索引,则其他两个条件不需要扫描超过几行使用索引找到的行,而不需要扫描--可能是- 50M行。
我看到所建议的索引的唯一原因是,如果CITY表有大量字段,并且索引将允许数据库从磁盘读取较少的数据以访问字段,那么所建议的索引将产生不小的影响。不是说是这样,但只有尝试才能肯定。
发布于 2013-02-23 15:06:21
在某些情况下,您可能需要重新考虑主键列上的聚集索引。
例如,如果您通常在给定城市中搜索商店(如果示例查询是“典型查询”,情况就是这样),那么将商店聚集在CityId上可能非常有益(这样,给定城市中的所有商店都会被分组)。
https://stackoverflow.com/questions/15041374
复制相似问题