从这一篇开始,准备总结一些直接受用的sql语句优化,写sql是第二要紧的,第一要紧的,是会分析怎么查最快,
因为当你写过很多sql后,查询出结果已经不是目标,快,才是目标。另外,通过测试和比较的结果才是有说服力的。
1、COUNT()查询
介绍:聚合函数。用于统计某个列值的数量,以及统计行数。如果统计列值要求列值非空,进一步,如果COUNT()
括号中指定了列或列的表达式,则统计这个表达式有值的结果(即表达式非空)。如果Mysql确认括号内表达式值不可能
为空,实际上会统计行数。再进一步,如果是COUNT(*)通配符,Mysql会忽略所有的列直接统计行数。
最后得出的结论是:如果想统计行数或结果集行数,不要在括号内指定具体的列或列的表达式,直接COUNT(*)
而COUNT(f(col_name))计算的是f(col_name)非空行数量。
另外值得注意的一点:COUNT(Expression= "xxx" OR NULL)表示统计表达式值为xxx的行数,当表达式值不等于
xxx时,Expression= "xxx"值为false,前面讲了count(xxx)函数的统计规则,结合or运算符可以推测下为什么需要加
OR NULL这个条件
其他的思路:使用Redis缓存计数,使用汇总表
2、关联查询
关联查询最需要优化的就是索引列
(1)ON子句的列要有索引,且只需要在第二个表的相应字段上建索引,但是优化器关联表的顺序需要测试和分析
(2)确保GROUP BY 和 ORDER BY的表达式只涉及到一个表中的列
3、子查询
不要使用,不要使用,除非有人拿枪逼着你使用,子查询改成关联查询
4、LIMIT分页
一个事实:offset非常大的时候,记录要扫描,但是结果集却会抛弃掉,比如 limit 10000,20,需要扫描10020条,但是
却只需要后面的20条。一般的做法是先计算出要返回的记录的第一条和最后一条的位置,比如这个例子是10000,10019,通
常这个表应该有一个自增的id,那么就是id between 10000,10019
另一种思路是在前端UI上分页的方式上下功夫,此处略去
5、UNION操作
在《高性能Mysql》一书中作者提到,Mysql总是通过创建并填充临时表的方式来执行UNION查询。而临时表是没有索引
优化的。除非确实需要消除重复的行,否则一定要用UNION ALL。如果没有ALL关键字,Mysql会给临时表加上DISTINCT选
项,也就是唯一性检查,这需要不小的代价
截止这篇,如果你能大致的理解Mysql是如何执行查询的,能手写项目中80%的sql,能设计出不错的表结构,索引,以及
学会测试和使用命令查询可能存在的优化漏洞,中等数据量的项目应该是没问题的。在接下来的篇章,笔者将在项目中实践一
些Mysql的高级特性。