如果对优化选择器的执行计划不满意,可以使用优化选择器提供的几个提示来控制最终的执行计划。可以用的提示如下所示:
HIGH_PRIORITY和LOW_PRIORITY
这两个提示用于告诉mysql,当多个语句的时候同时访问同一张表的时候,哪些语句的优先级高些,哪些语句的优先级低一些。
HIGH_PRIORITY用于SELECT语句的时候,Msql会将此SELECT语句重新调度到所有的正在等待表锁以便修改数据的语句之前。实际上Mysql是将其放在了表的队列的最前面,而不是简单的按常规顺序等待。
例如:select HIGH_PRIORITY * from people;
LOW_PRIORITY则正好相反:他会让语句一直处于等待的状态,只要队列中还有需要访问同一个表的语句-----即便是哪些比该语句还要晚提交到服务器的语句。这就像一个过于礼貌的人站在餐厅门口,只要还有其他顾客在等待就一直不进去,很明显会把自己给饿坏。LOW_PRIORITY提示在SELECT、INSERT、UPDATE和DELETE语句中都可以使用。
这两个提示只是对表锁的存储引擎有效,千万不要在InnoDB或者其他有细粒度的锁机制和并发控制的引擎中使用。
例如:update LOW_PRIORITY people set last_name =‘s‘
DELAYED
这个提示对INSERT和REPLACE有效。Mysql会将使用该提示的语句立即返回给客户端,并将插入的行数据放入到缓存区,然后在空闲时批量将数据导入。这个用法有一些限制:并不是所有的存储引擎都支持这样的做法,并且该提示还会导致LAST_INSERT_ID()无法正常工作。
例如:INSERT DELAYED INTO people set last_name =‘dff‘
STRAIGHT_JOIN
这个提示可以放置在SELECT关键字之后,也可以放置任何两个关联表的名字之间。第一个用法是让查询中所有的表按照语句中出现的顺序进行关联。第二个用法是固定其前后两个表的关联顺序。
例如:select STRAIGHT_JOIN * from people p INNER JOIN pseudohash pd on p.job_id = pd.id
SQL_SMALL_RESULT和SQL_BIG_RESULT
这两个提示只对SELECT有效。他们告诉优化器对GROUP BY或者DISTINCT查询如何使用临时表以及排序。SQL_SMALL_RESULT告诉优化器结果集会很小,可以将结果集放在内存的索引临时表中,以避免排序操作。如果是SQL_BIG_RESULT,则告诉优化器结果集可能会非常大,建议使用磁盘临时表做排序操作,这样就可以很快地释放MySQL的表锁(这样其它的SQL语句就可以对这些记录进行查询了)。
例如:select SQL_SMALL_RESULT gender from people GROUP BY gender
SQL_BUFFER_RESULT
这个提示告诉优化器将查询结果放入到一个临时表中,然后尽可能快的释放表锁。这个和前面提到的客户端缓存结果不同。当你没法使用客户端缓存的时候,使用服务器端的缓存通常会很有效。带来的好处是无须再客户端上面消耗很多的内存,还可以尽快的释放对应的表锁。代价是服务端将承受更多的内存。
列如:select SQL_BUFFER_RESULT * from people;
SQL_CACHE和SQL_NO_CCHE
这个提示告诉MYSQL这个结果是否应该放入查询缓存中去。
FOR UPDATE和LOCK IN SHARE MODE
这个也不是真正的优化器提示。这两个提示主要控制SELECT语句的锁机制,但是只对实现了行级锁的存储引擎有效,使用该提示会对符合查询条件的数据进行加锁。
USE INDEX、IGNORE INDEX和FORCE INDEX
这个几个提示会告诉优化器使用或者不使用哪些索引来查询记录,例如在决定关联顺序的时候使用哪个索引进行排序和分组。FORCE INDEX会告诉优化器全表扫描的成本会远远高于索引扫描,哪怕实际上该索引引用处不大。
IGNORE INDEX 忽略索引
列如:SELECT * FROM people IGNORE INDEX (last_name)
强制索引 FORCE INDEX
列如:SELECT * FROM people FORCE INDEX (last_name)