一、一些罕见的SQL实践
(1)负向前提查询不能运用索引
select * from order where status!=0 and stauts!=1
not in/not exists都不是好习惯
引荐 《mysql视频教程》
可以优化为in查询:
select * from order where status in(2,3)
(2)前导隐约查询不能运用索引
select * from order where desc like '%XX'
而非前导隐约查询则可以:
select * from order where desc like 'XX%'
(3)数据区分度不大的字段不宜运用索引
select * from user where sex=1
缘由:性别只要男,女,每次过滤掉的数据很少,不宜运用索引。
履历上,能过滤80%数据时就可以运用索引。关于定单状况,假如状况值很少,不宜运用索引,假如状况值许多,可以过滤大批数据,则应当竖立索引。
(4)在属性上举行盘算不能掷中索引
select * from order where YEAR(date) < = '2017'
纵然date上竖立了索引,也会全表扫描,可优化为值盘算:
select * from order where date < = CURDATE()
或许:
select * from order where date < = '2017-01-01'
二、并不是周知的SQL实践
(5)假如营业大部分是单条查询,运用Hash索引机能更好,比方用户中间
select * from user where uid=? select * from user where login_name=?
缘由:
B-Tree索引的时候复杂度是O(log(n))
Hash索引的时候复杂度是O(1)
(6)许可为null的列,查询有潜伏大坑
单列索引不存null值,复合索引不存全为null的值,假如列许可为null,可能会获得“不符合预期”的结果集
select * from user where name != 'shenjian'
假如name许可为null,索引不存储null值,结果集合不会包括这些纪录。
所以,请运用not null束缚以及默认值。
(7)复合索引最左前缀,并不是值SQL语句的where递次要和复合索引一致
用户中间竖立了(login_name, passwd)的复合索引
select * from user where login_name=? and passwd=? select * from user where passwd=? and login_name=?
都可以掷中索引
select * from user where login_name=?
也能掷中索引,满足复合索引最左前缀
select * from user where passwd=?
不能掷中索引,不满足复合索引最左前缀
(8)运用ENUM而不是字符串
ENUM保留的是TINYINT,别在罗列中搞一些“中国”“北京”“技术部”如许的字符串,字符串空间又大,效力又低。
三、小众但有效的SQL实践
(9)假如明白晓得只要一条结果返回,limit 1可以进步效力
select * from user where login_name=?
可以优化为:
select * from user where login_name=? limit 1
缘由:
你晓得只要一条结果,但数据库并不晓得,明白通知它,让它主动住手游标挪动
(10)把盘算放到营业层而不是数据库层,除了节约数据的CPU,另有意想不到的查询缓存优化结果
select * from order where date < = CURDATE()
这不是一个好的SQL实践,应当优化为:
$curDate = date('Y-m-d'); $res = mysql_query( 'select * from order where date < = $curDate');
缘由:
释放了数据库的CPU
屡次挪用,传入的SQL雷同,才可以应用查询缓存
(11)强迫范例转换会全表扫描
select * from user where phone=13800001234
你以为会掷中phone索引么?大错特错了,这个语句究竟要怎么改?
最后,再加一条,不要运用select *,只返回须要的列,可以大大的节约数据传输量,与数据库的内存运用量哟。
本文来自ki4网,mysql教程栏目,迎接进修!
以上就是不为人知的10条SQL语句优化的细致内容,更多请关注ki4网别的相干文章!