网站改版的目的,网络营销典型推广案例,linux 网站建设模板,成都工商注册官方网转载自 58沈剑 开源中国
一、一些常见的SQL实践
#xff08;1#xff09;负向条件查询不能使用索引 select * from order where status!0 and stauts!1
not in/not exists都不是好习惯
可以优化为in查询#xff1a; select * from order where status in(2,3)
#x…转载自 58沈剑 开源中国
一、一些常见的SQL实践
1负向条件查询不能使用索引 select * from order where status!0 and stauts!1
not in/not exists都不是好习惯
可以优化为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 sex1
原因性别只有男女每次过滤掉的数据很少不宜使用索引。
经验上能过滤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 phone13800001234
你以为会命中phone索引么大错特错了这个语句究竟要怎么改 末了再加一条不要使用select *潜台词文章的SQL都不合格 _只返回需要的列能够大大的节省数据传输量与数据库的内存使用量哟。
思路比结论重要希望你有收获。