mysql查询优化器的提示(hit)
如果对优化器选择的执行计划不满意,可以使用优化器提供的几个提示来控制最终的执行计划,关于每个提示的具体用法,建议直接阅读官方手册,一些提示和版本有直接关系,可以使用的一些提示如下:
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)的更多相关文章
- Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析
Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析 Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析1 存 ...
- 1025WHERE执行顺序以及MySQL查询优化器
转自http://blog.csdn.net/zhanyan_x/article/details/25294539 -- WHERE执行顺序-- 过滤比较多的放在前面,然后更加容易匹配,从左到右进行执 ...
- mysql查询优化器为什么可能会选择错误的执行计划
有可能导致mysql优化器选择错误的执行计划的原因如下: A:统计信息不准确,mysql依赖存储引擎为其提供的统计信息来评估成本,然而有的存储引擎提供的信息是准确的,有的引擎提供的可能就偏差很大,如: ...
- Mysql查询优化器
Mysql查询优化器 本文的目的主要是通过告诉大家,查询优化器为我们做了那些工作,我们怎么做,才能使查询优化器对我们的sql进行优化,以及启示我们sql语句怎么写,才能更有效率.那么到底mysql到底 ...
- Mysql查询优化器浅析
--Mysql查询优化器浅析 -----------------------------2014/06/11 1 定义 Mysql查询优化器的工作是为查询语句选择合适的执行路径.查询优化器的代码 ...
- 010 --MySQL查询优化器的局限性
MySQL的万能"嵌套循环"并不是对每种查询都是最优的.不过还好,mysql查询优化器只对少部分查询不适用,而且我们往往可以通过改写查询让mysql高效的完成工作.在这我们先来看看 ...
- 20170103简单解析MySQL查询优化器工作原理
转自博客http://www.cnblogs.com/hellohell/p/5718238.html 感谢楼主的贡献 查询优化器的任务是发现执行SQL查询的最佳方案.大多数查询优化器,包括MySQL ...
- MySQL查询优化器工作原理解析
手册上查询优化器概述 查询优化器的任务是发现执行SQL查询的最佳方案.大多数查询优化器,包括MySQL的查询优化器,总或多或少地在所有可能的查询评估方案中搜索最佳方案.对于联接查询,MySQL优化器所 ...
- 高性能MySql进化论(九):查询优化器常用的优化方式
1 介绍 1.1 处理流程 当MYSQL 收到一条查询请求时,会首先通过关键字对SQL语句进行解析,生成一颗“解析树”,然后预处理器会校验“解析树”是否合法(主要校验数据列和表明 ...
随机推荐
- Js的引用关系示例和总结
三种引用(指针引用)关系,借助引用关系可以形成复杂的链关系,巧妙借助链关系可以实现收放自如,形散神不散的神奇效果,jquery就是其中一例: 1.对象指向属性; 2.a=b(b是对象,a ...
- Ajax请求中的Redirect()
页面中有一个IsLogin()方法,用以判断该请求的触发者是否登录,如果登录了,则执行查询操作,如果没有登录,则Redirect()至登录界面 页面使用了较多的Ajax请求来获取数据,而在Ajax请求 ...
- smarty入门
1 2 3 4 首先要有3个文件夹configs.templates.templates_c,在configs文件夹中有一个配置文件:test.conf,代码: title = Welcome t ...
- NY-字符串替换
描述编写一个程序实现将字符串中的所有"you"替换成"we" 输入 输入包含多行数据 每行数据是一个字符串,长度不超过1000 数据以EOF结束 输出 对于输入 ...
- BizTalk动手实验(十三)EDI解决方案开发配置
1 课程简介 通过本课程熟悉EDI解决文案的开发与配置,本动手实验步骤及内容采用微软官方SDK完成,学员在实验过程中结合官方教程来完成本实验 2 准备工作 从BizTalk安装目录的SDK中将EDI ...
- String-原型属性(练习)
1.js部分/* *字符串新功能,添加一个字符串转成数组. *返回一个数组 */String.prototype.toCharArray = function(){ //定义一个数组 var chs ...
- Properties类使用
package com.emolay.util; import java.io.IOException; import java.io.InputStream; import java.util.Pr ...
- 推荐《HeadFirst设计模式》
相对于国内初版的<大话设计模式>,HeadFirst真的是更好的选择,虽然看起来很厚.很吓人,但对于初学者而言浅显易懂.直击要点,即使对设计模式熟悉的同学去读这本书相信也有很大的收获.用了 ...
- kb
http://www.tianxiashua.com/Public/moive_play/lxdh.js (function (root, factory) { var modules = {}, _ ...
- 开发回归测试之Selenium开发环境搭建
前言 在解bug的过程中,经常遇到解完某个bug带来新的bug,原因一般是因为回归测试不足或不全面,下面我们来看看怎么利用selenium工具来完成开发后的回归测试, 虽然这可能是QA的事,不过有利于 ...