只要说明几种日常用到的查询可以优化的地方,只是特别的情况下可以使用,不要期望任何情况下都成立,优化是一个实践的漫长过程!
一、最大值和最小值优化
对于min()和max()查询,MySQL的优化并不是很好,比方说:
select min(actor_id) from actor where first_name = 'Jane';
因为first_name上没有索引,所以这个会扫描全表。如果MySQL能按主键扫描,那么第一个满足条件的记录就是要找的最小指了,因为主键是严格按照大小顺序排列的,一个可以尝试的方法是不用min(),使用limit:
select actor_id from actor use index(primary) where first_name = 'Jane' limit 1;
但是这条SQL的本意就不明显了。
二、在同一个表上查询和更新
MySQL不允许对同一张表同时进行查询和更新,比方说
update tab1 as outer_tab
set cnt = (
select count(*) from tab1 as inner_tab
where inner_tab.type = outer_tab.type
);
可以使用生成表的形式绕过上面的限制,子查询会在update语句打开之前就完成。
update tab1
inner join(
select type,count(*) as cnt from tab1 group by type)
as der using(type)
set tab1.cnt = der.cnt;
三、使用优化器提示(hint)
这里之说明几个重要点的
1、DELAYED
这个提示对insert 和 replace有效。MySQL会将使用该提示的语句立即返回给客户端,并将插入的数据放到缓冲区,然后在表空闲时批量将数据写入。特别适合需要写入大量数据但是客户端却不需要等待语句完成I/O的应用。
2、STRAIGHT_JOIN
这个提示可以放在select语句的select关键字之后,也可以放在任何两个关联表的名字之间。第一个用法是让查询中所有的表按照在语句中出现的顺序进行关联。第二个用法则是固定前后两个表的关联顺序。当你可以确定某个关联顺序最佳的时候,可以使用,但是版本升级的时候要重新检查该类查询。
3、SQL_SMALL_RESULT 和 SQL_BIG_RESULT
这个提示只针对select语句有效。它告诉优化器对group by 或者 distinct查询如何使用临时表及排序。
4、SQL_BUFFER_RESULT
这个提示告诉优化器将查询结果放到一个临时表,然后尽可能快的释放表锁。
5、SQL_CACHE 和 SQL_NO_CACHE
这个提示告诉MySQL结果集是否应该缓存在查询缓存中。
6、FOR UPDATE 和 LOCK IN SHARE MODE
控制行锁,只针对InnoDB引擎,这个具体以后会有介绍。
7、USE INDEX、IGNORE INDEX 和 FORCE INDEX
使用或者不使用索引来查询记录。