不为人知的10条SQL语句优化
一、一些常见的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 *,只返回需要的列,能够大大的节俭数据传输量,与数据库的内存运用量哟。
本文来自 百分百源码网 ,mysql教程栏目,欢送学习!
以上就是不为人知的10条SQL语句优化的细致内容,更多请关注 百分百源码网 其它相干文章!