淡sqlserver对like '%关键词%' 处理时的索引利用问题
2015-11-23 11:17
323 查看
说法一:百分号%通配符前置会让SQL查询不走索引,改走全表扫描。这种说法很流行
结论是错误的
事实上这种说法不太准确 通配符%前置会让SQL查找索引时效率极速下降,但在大多数情况下还是会走索引(不需要全文索引,只要建一个普通的索引就可以了)
CREATE NONCLUSTERED INDEX [Ix_索引名] ON [dbo].[wkf_表名]
(
[db_title] ASC
)
此时执行
SELECT top 10 [db_id],[db_Summary],[db_AddDate],[db_title] FROM [库名].[dbo].[wkf_database] where [db_title]like '%dba%' order by 1 desc
查询计划显示得很清楚
对比加索引之前:
说一个例外,复杂查询查询优化器可能会抛弃索引改走全表扫描。这不仅是LIKE '%关键词%' 时会这样,跟查询复杂度有关
说法二:百分号%通配符前置会让SQL查询走索引不如不走索引
这种说法非常片面,走索引比不走索引99%的情况下都会减少IO从而提高效率,但是:索引查找完的键匹配动作也是有一部分性能消耗的。像上面两张图所示,如果关键字很容易就匹配到了,全表扫描很快就找齐了数据,而索引扫描节省的时间不足以弥补键匹配动作所消耗时间的时候这种情况就发生了(大部分线上查询不存在这问题)这时候优化就变得诡异了。
处理方法:
1.不去管它,多出来的性能消耗不是很大。而且不同的关键词有不同的消耗,只是部分关键词存在此问题,可以忽略
2.更好的方法,如果条件允许建覆盖索引(又叫INCLUDE索引)。前题条件:a存储空间充足,b不显著影响DML操作,c覆盖的索引中没有大字段
CREATE NONCLUSTERED INDEX [Ix_索引名] ON [dbo].[wkf_表名]
(
[db_title] ASC
)
INCLUDE ( [db_id],[db_Summary],[db_AddDate])
此时执行查询计划如下,清爽多了吧
以上就是我现在能想到的SQLSERVER处理SELECT * FROM TABLENAME LIKE '%关键词%'
总结:
1.使用模糊查询最好使用后置,前置会大大降低效率。
select * from T_OMS_EMPLOYEE_BASEINFOR where usernameCn like '%肖%'
2.使用全文检索,效率远远大于like,不过具体全文检索怎么操作我还没有学习,这边就不能给我例子。(待学习)
结论是错误的
事实上这种说法不太准确 通配符%前置会让SQL查找索引时效率极速下降,但在大多数情况下还是会走索引(不需要全文索引,只要建一个普通的索引就可以了)
CREATE NONCLUSTERED INDEX [Ix_索引名] ON [dbo].[wkf_表名]
(
[db_title] ASC
)
此时执行
SELECT top 10 [db_id],[db_Summary],[db_AddDate],[db_title] FROM [库名].[dbo].[wkf_database] where [db_title]like '%dba%' order by 1 desc
查询计划显示得很清楚
对比加索引之前:
说一个例外,复杂查询查询优化器可能会抛弃索引改走全表扫描。这不仅是LIKE '%关键词%' 时会这样,跟查询复杂度有关
说法二:百分号%通配符前置会让SQL查询走索引不如不走索引
这种说法非常片面,走索引比不走索引99%的情况下都会减少IO从而提高效率,但是:索引查找完的键匹配动作也是有一部分性能消耗的。像上面两张图所示,如果关键字很容易就匹配到了,全表扫描很快就找齐了数据,而索引扫描节省的时间不足以弥补键匹配动作所消耗时间的时候这种情况就发生了(大部分线上查询不存在这问题)这时候优化就变得诡异了。
处理方法:
1.不去管它,多出来的性能消耗不是很大。而且不同的关键词有不同的消耗,只是部分关键词存在此问题,可以忽略
2.更好的方法,如果条件允许建覆盖索引(又叫INCLUDE索引)。前题条件:a存储空间充足,b不显著影响DML操作,c覆盖的索引中没有大字段
CREATE NONCLUSTERED INDEX [Ix_索引名] ON [dbo].[wkf_表名]
(
[db_title] ASC
)
INCLUDE ( [db_id],[db_Summary],[db_AddDate])
此时执行查询计划如下,清爽多了吧
以上就是我现在能想到的SQLSERVER处理SELECT * FROM TABLENAME LIKE '%关键词%'
总结:
1.使用模糊查询最好使用后置,前置会大大降低效率。
select * from T_OMS_EMPLOYEE_BASEINFOR where usernameCn like '%肖%'
2.使用全文检索,效率远远大于like,不过具体全文检索怎么操作我还没有学习,这边就不能给我例子。(待学习)
相关文章推荐
- 配置NHibernate将枚举保存为Oracle数据库中的字符串
- symfony数据库方法位置
- sql实现不同的需求
- SQLServer 2008以上误操作数据库恢复方法——日志尾部备份
- Oracle数据库 sql%found,sql%notfound,sql%rowcount
- Oracle queue - sql
- 谈谈Memcached与Redis
- SQL回炉系列(五) 为显示曲线图获取不同时间颗粒的数据
- MySql查询结果按照指定顺序排序
- sql server 2008基础
- SQL回炉系列(四) 删除重复数据
- datetime和timestamp区别
- sql%rowcount
- SSDB:高性能数据库服务器
- 关于SQL注入,你应该知道的那些事
- 有关sql写法注意
- Oracle外部表
- SQL回炉系列(三) 拆分原始数据到对应的月份表中
- sql sum等函数
- H2数据库攻略