如果对优化器选择的执行计划不满意,可以使用优化器提供的几个提示来控制最终的执行计划,关于每个提示的具体用法,建议直接阅读官方手册,一些提示和版本有直接关系,可以使用的一些提示如下:

high_priority和low_priority:

  这个提示告诉mysql,当多个语句同时访问某一个表的时候,哪些语句的优先级相对高一些,哪些语句的优先级相对低一些。

  high_priority用于select语句的时候,mysql会将其放到表的队列的最前面,而不是按照常规顺序等待,high_priority还可以用于insert语句,其效果只是简单地抵消了全局low_priority设置对该语句的影响。

  low_priority则更好相反,它会让该语句一直处于等待状态,只要队列中还有需要访问同一个表的语句,即使是后到的请求也会插到该语句的前面去。很明显,容易把自己给饿死,low_priority提示在select,insert,update和delete语句中都可以使用。

注意:这两个提示只对使用表锁的存储引擎有效,千万不要在innodb或者其他有细粒度锁机制和并发控制的引擎中使用,即使是在myisam中使用也要注意,因为这两个提示会导致并发插入被禁用,可能会严重降低性能。这两个提示只是简单地控制了mysql访问某个数据表的队列顺序,仅此而已。

delayed:

  这个提示对insert和replace有效,mysql会将使用该提示的语句立即返回给客户端,并将插入的行数据当如到缓冲区,然后在表空闲时批量将数据写入,日志系统使用这样的提示非常有效,或者是其他需要写入大量数据但是客户端却不需要等待单挑语句完成的IO应用。但这个用法有一些喜爱你知,并不是所有的存储引擎都支持 ,并且该提示会导致函数last_insert_id()无法正常工作。

straight_join:

  这个提示可放置在select关键字之后,也可以放置在任何两个关联表的表名之前,第一个用法是让查询中所有的表按照在语句中出现的顺序进行关联,第二个用法则是固定其前后两个表的关联顺序。当mysql没正确选择关联顺序的时候,或者由于可能的顺序太多导致mysql无法评估所有的关联顺序的时候,straight_join都会很有用,如果关联表可能的顺序太多,可能导致mysql花费大量时间在statistics状态。可以使用explain语句来查看关联顺序,然后加上这个提示再用explain查看有没有变化。

sql_small_result和sql_big_result:

  这两个提示只对select有效,他们告诉优化器对group by或者distinct查询如何使用临时表及其排序,sql_small_result告诉优化器结果集会很小,可以将结果集放在内存的索引临时表,以避免排序操作,如果是sql_big_result,则告诉优化器结果集可能非常大,建议使用磁盘临时表做排序操作。

sql_cache和sql_no_cache:

  这个提示告诉mysql这个结果集是否应该缓存在查询缓存中,如:select sql_cache|sql_no_cache * from tb_name,紧跟在select关键字后面。

sql_calc_found_rows:

  严格来说,这个并不是一个优化器提示,它不会告诉优化器任何关于执行计划的东西,它会让mysql返回的结果集包含更多的相关信息,查询中加上该提示mysql会计算除去limit子句后这个查询要返回的结果集的总数。而实际上只返回limit要求的结果集,结果集总数可以通过found_row()获得这个值。一般不要使用这个提示

for update和lock in share mode:

  这也不是真正的优化器提示,这两个提示主要控制select语句的锁机制,但只对实现了行级锁的引擎有效,使用该提示对符合查询条件的数据行加锁,对于insert .. select语句是不需要这两个提示的,因为对于mysql5.0和更新的版本会默认给这些记录加上读锁。内置的支持这两个提示的引擎就是innodb,另外需要记住的是,这两个提示会让某些优化无法正常使用,如:索引覆盖扫描,innodb不能在不访问主键的情况下排他地锁定行,因为行的版本信息保存在主键中。这两个提示经常被开发滥用,很容易造成服务器的锁争用问题,应该尽可能地避免使用这两个提示。通常可以使用其他更好的方式来实现同样的目的。

use index,ignore index和force index:

  这几个提示告诉优化器使用或者不使用或者强制使用哪些所以来查询记录。在mysql5.0和更早的版本中,这些提示并不会影响到优化器选择那个索引进行排序和分组,在5.1和之后

的版本可以通过新增选项for order by和for group by来指定是否对排序和分组有效。force index和use index基本相同,除了一点,force index会告诉优化器全表扫描的成本远远高于索引扫描。哪怕实际上该索引用处不大。优化器也会使用force index指定的索引。

在mysql5.0和更新的版本中,新增了一些参数来控制优化器的行为:

optimizer_search_depth:

  这个参数控制优化器在穷举执行计划时的限度,如果查询长时间处于statistics状态,那么可以考虑调低此参数的值,默认为62,即,这个也控制了最大关联表数量。

optimizer_prune_level:

  该参数默认是打开的,为1,这让优化器会根据需要扫描的行数来决定是否跳过某些执行计划

optimizer_switch:

  这个变量包含了一些开启/关闭优化器特性的标志位,如:mysql5.1中可以通过这个参数来控制禁用索引合并的特性。

  5.5默认为:

index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on

  5.6默认为:

index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,subquery_materialization_cost_based=on,use_index_extensions=on

  这三个参数,前两个参数是用来控制优化器可以走一些捷径的,这些捷径可以让优化器在处理非常复杂的SQL语句时,仍然可以很高效,但这也可能让优化器错过一些真正最优的执行计划,所以应该根据实际需要来修改这些参数。

  要注意:在优化器面前耍小聪明是不好的,因为这样做不但收效甚微,而且给后期维护带来了很多额外的工作量,在mysql版本升级的时候,这个问题就很突出了,你设置的优化器提示很可能会让新版的优化器的优化策略失效。除非特殊需要,否则不要使用这些提示来改变默认的执行计划。mysql5.5和5.6在各方面都有非常大的改进,一般来说升级都很顺利,但仍然建议检查各个细节,可以使用percona toolkit中的pt-upgrade工具来检查在新版本中运行的SQL是否与老版本一样,返回相同的结果。

mysql查询优化器的提示(hit)的更多相关文章

  1. Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析

    Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析     Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析1 存 ...

  2. 1025WHERE执行顺序以及MySQL查询优化器

    转自http://blog.csdn.net/zhanyan_x/article/details/25294539 -- WHERE执行顺序-- 过滤比较多的放在前面,然后更加容易匹配,从左到右进行执 ...

  3. mysql查询优化器为什么可能会选择错误的执行计划

    有可能导致mysql优化器选择错误的执行计划的原因如下: A:统计信息不准确,mysql依赖存储引擎为其提供的统计信息来评估成本,然而有的存储引擎提供的信息是准确的,有的引擎提供的可能就偏差很大,如: ...

  4. Mysql查询优化器

    Mysql查询优化器 本文的目的主要是通过告诉大家,查询优化器为我们做了那些工作,我们怎么做,才能使查询优化器对我们的sql进行优化,以及启示我们sql语句怎么写,才能更有效率.那么到底mysql到底 ...

  5. Mysql查询优化器浅析

    --Mysql查询优化器浅析 -----------------------------2014/06/11 1 定义    Mysql查询优化器的工作是为查询语句选择合适的执行路径.查询优化器的代码 ...

  6. 010 --MySQL查询优化器的局限性

    MySQL的万能"嵌套循环"并不是对每种查询都是最优的.不过还好,mysql查询优化器只对少部分查询不适用,而且我们往往可以通过改写查询让mysql高效的完成工作.在这我们先来看看 ...

  7. 20170103简单解析MySQL查询优化器工作原理

    转自博客http://www.cnblogs.com/hellohell/p/5718238.html 感谢楼主的贡献 查询优化器的任务是发现执行SQL查询的最佳方案.大多数查询优化器,包括MySQL ...

  8. MySQL查询优化器工作原理解析

    手册上查询优化器概述 查询优化器的任务是发现执行SQL查询的最佳方案.大多数查询优化器,包括MySQL的查询优化器,总或多或少地在所有可能的查询评估方案中搜索最佳方案.对于联接查询,MySQL优化器所 ...

  9. 高性能MySql进化论(九):查询优化器常用的优化方式

    1        介绍 1.1     处理流程 当MYSQL 收到一条查询请求时,会首先通过关键字对SQL语句进行解析,生成一颗“解析树”,然后预处理器会校验“解析树”是否合法(主要校验数据列和表明 ...

随机推荐

  1. Js中this用法及注意点详解

          我们在写js时,特别是用到回调函数时,经常会发现this指代的对象总是可能脱离自己的思路而发生改变.面向对象语言的特性告诉我们this始终指代它的调用者,而在js中回调函数中内部的this ...

  2. zk回车事件

    private Textbox testTextB; testTextB.addEventListener(Events.ON_OK, new EventListener<Event>() ...

  3. 开启ACM的征途

    ACM对我的诱惑实在是太大了.以前从没有任何一件事情让我在假期也这么热血沸腾过,甚至是高考,也从没有过. 我对ACM的目标从没变过,我要拿金牌,我要进WF! 尽管我现在才刚刚开始ACM之旅,尽管我现在 ...

  4. vbox下Oracle Enterprise liunx5.4虚拟机安装10G RAC实验(四)

    接第3篇 http://www.cnblogs.com/myrunning/p/4003527.html 5.安装配置数据库 5.1安装数据库软件 5.2配置监听 5.3创建ASM磁盘 5.4创建服务 ...

  5. 一次熬夜解决的java乱码问题

    在java  API中String有一个方法 public byte[] getBytes() Encodes this String into a sequence of bytes using t ...

  6. bootstrap 不兼容ie8 的问题

    官方推荐的脚手架中,其实已经包含着解决方案:html5shiv.min.js .Respond.min.js 但由于respond.js  使用 file:// 协议,IE8 是无法调起本地文件的   ...

  7. Java中this关键字的几种用法

    1 . 当成员变量和局部变量重名时,在方法中使用this时,表示的是该方法所在类中的成员变量.(this是当前对象自己) 如:public class Hello { String s = " ...

  8. Java NIO 网络编程基础

    Java NIO提供了一套网络api,可以用来处理连接数很多的情况.他的基本思想就是用一个线程来处理多个channel. 123456789101112131415161718192021222324 ...

  9. shutter截图工具

    安装: 1.打开ubuntu software center,搜索shutter,安装. 使用:

  10. scala在linux以及在windows的安装,以及在IDEA中新建Scala项目

    一:linux下配资scala 1.上传 2.解压 3.配置环境 4.source一下 5.启动和简单使用 6.输出语句 二:scalac的使用 1.新建文件测试目录 2.新建程序 3.文件编译器书写 ...