背景:生产环境SQL语句查询过慢(数据总量在350万左右),日志中心一直报警
解决过程:分析无果后,求助于公司的DBA,DBA分析后建议在语句中指定索引
解决:在SQL语句中指定索引,效果相当明显,亲测有效
优化前SQL:
- SELECT ROW_NUMBER() OVER ( ORDER BY sc.ModifyTime DESC ) AS RowNumber ,
- sc.CommodityCode AS ChannelCommodityCode ,
- sc.OutShopCommodityCode AS OutItemId ,
- sc.IsShelf ,
- sc.OriginPrice ,
- sc.SalePrice ,
- sc.CreateBy ,
- sc.CreateTime ,
- sc.ModifyTime ,
- sc.StoreCode ,
- sc.ShopCommodityId AS ChannelStoreMappingId ,
- sc.ShopCommodityName AS O2OCommodityName ,
- sc.ShopCommodityTitle AS O2OCommodityTitle ,
- sc.Remark AS Comment ,
- sc.OutShopSPUCode ,
- sc.ModifyBy ,
- sc.ChannelCode
- FROM dbo.Channel_ShopCommodity AS sc WITH ( NOLOCK )
- WHERE sc.Disabled = 0
- AND sc.ChannelCode = '9000000009'
- AND sc.CityId = 'eabbe02f-59e0-46e6-90e7-cd8a89dbb98f';
优化后SQL(指定使用索引IX_CityId):
- SELECT ROW_NUMBER() OVER ( ORDER BY sc.ModifyTime DESC ) AS RowNumber ,
- sc.CommodityCode AS ChannelCommodityCode ,
- sc.OutShopCommodityCode AS OutItemId ,
- sc.IsShelf ,
- sc.OriginPrice ,
- sc.SalePrice ,
- sc.CreateBy ,
- sc.CreateTime ,
- sc.ModifyTime ,
- sc.StoreCode ,
- sc.ShopCommodityId AS ChannelStoreMappingId ,
- sc.ShopCommodityName AS O2OCommodityName ,
- sc.ShopCommodityTitle AS O2OCommodityTitle ,
- sc.Remark AS Comment ,
- sc.OutShopSPUCode ,
- sc.ModifyBy ,
- sc.ChannelCode
- FROM dbo.Channel_ShopCommodity AS sc WITH ( NOLOCK, INDEX= [IX_CityId] )
- WHERE sc.Disabled = 0
- AND sc.ChannelCode = '9000000009'
- AND sc.CityId = 'eabbe02f-59e0-46e6-90e7-cd8a89dbb98f';
注意事项:使用指定索引后,必须保证Where条件中有这个筛选条件,否则索引不生效,查询语句耗时仍然会很长
- SELECT ROW_NUMBER() OVER ( ORDER BY sc.ModifyTime DESC ) AS RowNumber ,
- sc.CommodityCode AS ChannelCommodityCode ,
- sc.OutShopCommodityCode AS OutItemId ,
- sc.IsShelf ,
- sc.OriginPrice ,
- sc.SalePrice ,
- sc.CreateBy ,
- sc.CreateTime ,
- sc.ModifyTime ,
- sc.StoreCode ,
- sc.ShopCommodityId AS ChannelStoreMappingId ,
- sc.ShopCommodityName AS O2OCommodityName ,
- sc.ShopCommodityTitle AS O2OCommodityTitle ,
- sc.Remark AS Comment ,
- sc.OutShopSPUCode ,
- sc.ModifyBy ,
- sc.ChannelCode
- FROM dbo.Channel_ShopCommodity AS sc WITH ( NOLOCK, INDEX= [IX_CityId] )
- WHERE sc.Disabled = 0
- AND sc.ChannelCode = '9000000009'
- AND sc.StoreCode IN ( '10000723' );
以下截图为上面语句的耗时:

去除指定索引后再次执行
- SELECT ROW_NUMBER() OVER ( ORDER BY sc.ModifyTime DESC ) AS RowNumber ,
- sc.CommodityCode AS ChannelCommodityCode ,
- sc.OutShopCommodityCode AS OutItemId ,
- sc.IsShelf ,
- sc.OriginPrice ,
- sc.SalePrice ,
- sc.CreateBy ,
- sc.CreateTime ,
- sc.ModifyTime ,
- sc.StoreCode ,
- sc.ShopCommodityId AS ChannelStoreMappingId ,
- sc.ShopCommodityName AS O2OCommodityName ,
- sc.ShopCommodityTitle AS O2OCommodityTitle ,
- sc.Remark AS Comment ,
- sc.OutShopSPUCode ,
- sc.ModifyBy ,
- sc.ChannelCode
- FROM dbo.Channel_ShopCommodity AS sc WITH ( NOLOCK )
- WHERE sc.Disabled = 0
- AND sc.ChannelCode = '9000000009'
- AND sc.StoreCode IN ( '10000723' );

我们会发现耗时明显减少。
由此总结:如果确保某个条件一定会传并且该字段上加了索引,可以使用指定索引提升性能,但是使用指定索引要慎重,避免因为指定索引的Where条件不传又引起的查询耗时变长