MySQL 影响SQL查询速度

来源:互联网 发布:王牌特工特工学院淘宝 编辑:程序博客网 时间:2024/05/21 18:48

查询速度为什么会慢

SQL请求处理步骤

  1. 客户端发送SQL请求给MySQL服务器
  2. MySQL服务器会在查询缓存中进行检查,查看是否可以在查询缓存中命中
  3. 服务端会对SQL进行解析、预处理再由优化器生成对应的执行计划
  4. 根据执行计划,调用存储引擎中的API来查询数据
  5. 将查询的数据返回给客户端,必要的时候进行缓存过滤

查询缓存

如果查询缓存开关是打开的会优先对缓存中检查:
这个检查是对大小写敏感的hash查找实现:so,只能进行全值匹配查找。
如果在缓存中命中查询结果,会进行角色的权限认证,然后跳过后面的步骤把数据返回给客户端。
1. 查询的SQL要和缓存中的完全一致,所以命中并不容易。
2. 如果缓存中的数据是正确的,需要每次修改表的时候进行缓存的维护。
3. 而且进行缓存中查找的同时会对表加锁,所以对读写频繁的应用,查询缓存很可能降低查询效率(不建议开启查询缓存)

查询缓存相关参数

query_cache_type:
0代表关闭查询缓存OFF,1代表开启ON,2(DEMAND)代表当sql语句中有SQL_CACHE关键词时才缓存。
例:select SQL_CACHE user_name from users where user_id = ‘100’;
query_cache_size:
表示查询缓存大小,也就是分配内存大小给查询缓存,分配大小为1024整数倍;设置为0表示不缓存
query_cache_limit :
控制缓存查询结果的最大值
MySql 可以设置一个最大的缓存值,当你查询缓存数结果数据超过这个值就不会
进行缓存。缺省为1M,也就是超过了1M查询结果就不会缓存。
在 query_cache_type 打开的情况下,如果你不想使用缓存,需要使用sql_no_cache关键字
例:select sql_no_cache id,name from tableName;
query_cache_wlock_invalidate:
如果一个表被加锁是否允许直接从缓存中读取结果,默认为FALSE。
query_cache_min_res_unit:
查询缓存中存放的最小内存大小,默认4k;

SQL转变为执行计划

  1. 解析SQL
    语法解析阶段是通过关键字对mysql进行语法解析并生成一颗对应的解析树
    此阶段,使用MySQL语法规则验证和解析查询:检查语法是否使用的正确的关键字和关键字的位置是否正确
  2. 预处理
    预处理阶段进一步的验证检查解析树是否合法
    此阶段检查查询中所涉及的表和数据列是否存在及名字或者别名是否有存在歧义
  3. 优化SQL执行计划
    查询优化器生成查询计划

影响查询计划生成的因素

  1. 统计信息不准确
  2. 执行计划中的成本估算并不等于实际的执行计划成本
    mysql服务器层并不知道哪些页面在内存中,哪些页面在磁盘中,哪些页面顺序读,哪些页面要随机读
  3. mysql所认为的最优可能和我们所认为的最优并不一致
    mysql基于其成本模型选择最优的执行计划
  4. mysql不会考虑到其他的并发查询
  5. 有时候也会基于一些固定的规则来生成执行计划
  6. mysql不会考虑不受其控制的成本,如:存储过程和用户自定义的函数

MySQL可以优化的SQL类型

  1. mysql会重新定义标的关联顺序
  2. 将外链接转换成内连接
  3. 使用等价变换原则
  4. 可以利用索引对count(),min(),max()进行优化。如最小值 btree索引第一个数据
  5. 将表达式转化为一个常数
  6. 子查询优化:把子查询转换成关系查询
  7. 会提前终止查询:如发现不成立的条件,如属性设置为正数,查询条件是负数
  8. 对in()进行优化,会对in中的数据进行排序,然后进行二分查找

如何确定查询各个阶段所消耗的时间

profile

Profiling是从 mysql5.0.3版本以后才开放的。
启动profile之后,所有查询包括错误的语句都会记录在内。
profile是一个session级别的配置,关闭会话或者set profiling=0 就关闭了。(如果将profiling_history_size参数设置为0,同样具有关闭MySQL的profiling效果。)
show profiles
show profile for query N 查询每个阶段所消耗的时间
5.5之后使用performance_schma

原创粉丝点击