本文将介绍如何优化特定类型的查询。

1.优化count()查询
count()聚合函数,以及如何优化使用了该函数的查询,很可能是mysql中最容易被误解的前10个话题之一

count() 是一个特殊的函数,有两种非常不同的作用。它可以统计某个列值的数量,也可以统计行数。
统计列值 要求列值是非空的。(不统计null,即null值计数为0)

count()的另一个用处是统计结果集的行数。当mysql确认括号的表达式值不可能为空时,实际上就是统计行数。最简单的就是当我们使用count(*)的时候,这种情况下统配符*并不会像我们猜想的那样扩展成所有的列,实际上,它会忽略所有的列而直接统计所有的行数。

假如在同一个查询中统计同一个列不同值得数量

select sum(if(color = 'blue', 1, 0)) as BLUE, sum(if(color = 'red', 1, 0)) as RED from items

select count(color= 'blue' or null) blue, count(color= 'red' or null) red, from items

2.优化关联查询
这个话题讨论的比较频繁,这里需要特别提到的是:

2.1、确保on或者using子句中的列上有索引。在创建索引的时候就要考虑到关联的顺序。

    当表A和表B用列c关联的时候,如果优化器关联的顺序是A、B,那么就不需要在A表的对应列上创建索引。没有用到的索引会带来额外的负担,一般来说,除非有其他理由,只需要在关联顺序中的第二张表的相应列上创建索引(具体原因下文分析)。

2.2、确保任何的group by 和order by 的表达式只涉及到一个表中的列。这样mysql才有可能使用索引来优化这个过程
2.3、当升级mysql的时候需要注意:关联语法,运算符优先级等其他可能会发生变化的地方。

示例说明:

SELECT A.xx,B.yy
FROM A INNER JOIN B USING(c)
WHERE A.xx IN (5,6)
假设MySQL按照查询中的关联顺序A、B来进行关联操作,那么可以用下面的伪代码表示MySQL如何完成这个查询:
outer_iterator = SELECT A.xx,A.c FROM A WHERE A.xx IN (5,6);
outer_row = outer_iterator.next;
while(outer_row) {
inner_iterator = SELECT B.yy FROM B WHERE B.c = outer_row.c;
inner_row = inner_iterator.next;
while(inner_row) {
output[inner_row.yy,outer_row.xx];
inner_row = inner_iterator.next;
}
outer_row = outer_iterator.next;
}
可以看到,最外层的查询是根据A.xx列来查询的,A.c上如果有索引的话,整个关联查询也不会使用。再看内层的查询,很明显B.c上如果有索引的话,能够加速查询,因此只需要在关联顺序中的第二张表的相应列上创建索引即可。

3.优化子查询
尽可能用关联代替。

4.优化group by 和 distinct
在很多场景下,mysql都使用同样的方法优化这两种查询,事实上,mysql优化器会在内部处理的时候相互转化这两类查询。他们都可以使用索引来优化,这也是最有效的优化方法。

优化 group by with rollup
分组查询的一个变种就是要求mysql对返回的分组结果再做一次超级聚合。你可以使用with rollup来实现这种优化。最好的办法是尽可能将with rollup 功能转移到应用程序处理。

5.优化limit和offset
在系统需要进行分页操作的时候,我们通常会使用LIMIT加OFFSET的办法来实现,同时加上合适order by子句。
如果有对应的索引,通常效率会不错,否则,mysql需要做大量的文件排序。

在OFFSET大的时候,查询会很糟糕。要优化这种查询,要么是在页面中限制分页的数量,要么优化大偏移量查询的性能。

优化此类分页查询最简单的一个方法是使用索引覆盖扫描,而不是查询所有的列。
然后根据一次关联操作再返回需要的列。在偏移量很大的时候,这样会大大提升效率:

mysql> SELECT film_id, description FROM sakila.film ORDER BY title LIMIT 50, 5;
--优化后
mysql> SELECT film.film_id, film.description
  -> FROM sakila.film
  -> INNER JOIN (
  -> SELECT film_id FROM sakila.film
  -> ORDER BY title LIMIT 50, 5
  -> ) AS lim USING(film_id);

这里的"延迟查询"将大大提升查询效率,它让mysql扫描尽可能少的页面,获取需要访问的记录后再
根据关联列回原表查询需要的列。这个技术也可以用于优化关联查询中的limit子句。

有时候也可以将limit查询转换为已知位置的查询,让mysql通过范围扫描获得到对应的结果。

6.优化 SQL_CALC_FOUND_ROWS
分页的时候,另一个常用的技巧是在limit语句中加上SQL_CALC_FOUND_ROWS提示(hint),这样就可以获取去掉limit以后满足条件的行数,因此可以作为分页的总数。看来,mysql做了非常"高深"的优化,像是通过某种方法预测了总行数。但实际上,mysql只有再扫描所有满足条件的行以后才知道行数,所以加上这个提示以后,不管是否需要,mysql都会扫描所有满足条件的行,然后再抛弃不需要的行,而不是在满足limit的行数后就终止扫描。所以该提示的代价可能非常高。

7.优化union查询
mysql总是通过创建并填充临时表的方式来执行union查询。因此很多优化策略在union查询中都没法很好的使用。经常需要手工地将where,limit,order by等子句下推到union的各个子查询中,以便优化器可以充分利用这些条件进行优化。

除非确实需要服务器消除重复的行,否则一定要使用union all ,这一点很重要。
如果没有ALL关键字,mysql会给临时表加上distinct选项,这会导致对整个临时表的数据唯一检查。这样的代价非常高。即使有ALL关键字,mysql仍然会使用临时表存储结果。
事实上,mysql总是将结果放入临时表,然后再读出,再返回给客户端,很多时候这样做是没有必要的。

8.静态查询分析

9.使用用户自定义变量
set @one := 1

mysql查询优化之四:优化特定类型的查询的更多相关文章

  1. MySQL优化特定类型的查询

    优化关联查询 如果想要优化使用关联的查询,我们需要特别留意以下几点: 确保ON或者USING子句中的列上有索引.在创建索引的时候需要考虑到关联的顺序.当表A和表B用列c关联的时候,如果优化器的关联顺序 ...

  2. MySQL 优化特定类型的查询

    优化COUNT()查询 COUNT() 是一个特殊的函数,有两种非常不同的作用: 统计某个列值的数量,也可以统计行数.在统计列值时要求列值是非空的(不统计NULL ).如果在COUNT() 的括号中指 ...

  3. mysql 查询优化~ 分页优化讲解

    一 简介:今天咱们来聊聊mysql的分页查询二 语法     LIMIT [offset,] rows     offset是第多少条     rows代表多少条之后的行数    性能消耗    se ...

  4. mysql 查询优化~sql优化通用

    一 简介:今天我们来探讨下SQL语句的优化基础 二 基础规则: 一 通用: 1 避免索引字段使用函数     2 避免发生隐式转换     3 order by字段需要走索引,否则会发生filesor ...

  5. php面试专题---18、MySQL查询优化考点

    php面试专题---18.MySQL查询优化考点 一.总结 一句话总结: 慢查询:查找分析查询速度慢的原因 数据访问:优化查询过程中的数据访问 长难句:优化长难的查询语句 特定类型:优化特定类型的查询 ...

  6. mysql高性能6章总结(下) mysql查询优化

    6.5查询优化器的局限性 mysql优化器是有局限性的,有时需要我们改写查询以提高效率. 6.5.1关联子查询 子查询是mysql一个很不效率的地方. 这一节首先我们需要了解一下相关子查询:内外部查询 ...

  7. mysql查询优化之一:mysql查询优化常用方式

    一.为什么查询速度会慢? 一个查询的生命周期大致可以按照顺序来看:从客户端,到服务器,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端.其中在“执行”阶段包含了大量为了检索数据到存储引擎 ...

  8. PHP面试 MySQL查询优化

    MySQL查询优化 面试题一 请简述项目中优化SQL语句执行效率的方法,从那些方面,SQL语句性能如何分析? 优化查询过程中的数据访问.优化长难的查询语句.优化特定类型的查询语句 分析SQL语句方法 ...

  9. Mysql查询优化器浅析

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

随机推荐

  1. lvm创建 及 扩空 等相关

    1.先对磁盘进行LVM 设置 2.pvcreate  物理卷的创建 pvcreate /dev/### 3.vgcreate 物理卷组的创建 vgcreate  vg_name  /dev/###  ...

  2. hdu2509 Be the Winner 博弈

    Let's consider m apples divided into n groups. Each group contains no more than 100 apples, arranged ...

  3. linux kernel笔记

    文章目录 关于linux内核中的__attribute__关键字 Linux kernel启动参数 gdt / ldt PCB 关于linux内核中的__attribute__关键字 part I: ...

  4. day 49 html 学习 css 学习

    画圆 <style> div{width: 100px; height:100px; border: solid red 3px; /*当弧度为.圆角半径为30时 得到的图像*/ bord ...

  5. 【转载】Win10打开U盘提示“文件或目录损坏无法读取”怎么办?

    以下文转载至系统之家 网址:http://www.xitongzhijia.net/xtjc/20190314/152334.html (PS:暂未亲测) Win10打开U盘提示“文件或目录损坏无法读 ...

  6. HDU1370(中国剩余定理)

    昨天我细致一想,发现自己之前的分类(用OJ来划分,毫无意义啊.)太失败了,所以我又一次划分了一下大分类,在分到数论的时候,我就想起了中国剩余定理了.于是乎今天就刷了一题中国剩余定理的题目了.话说太久没 ...

  7. Python_getter和setter方法

    当给属性赋值的时候,使用实例.属性=属性值的方式显然把属性暴露出来了,并且也无法对属性值进行限制检查,java中提供了setter和getter方法,那么python是如何做的呢?更多内容请参考:Py ...

  8. MySQL管理实务处理

    事物处理可以用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么全不执行. 事务:指一组sql语句 回退:指撤销指定的sql语句过程 提交:将未存储的sql语句结果写入数据库表 保留点 ...

  9. 关注 硬件 发展, 转载一篇介绍 VHDL 的文章

    <VHDL学习笔记> https://www.eefocus.com/hrbeulvcaho/blog/12-11/289109_978e2.html VHDL 和  “可编程逻辑阵列”  ...

  10. YUICompressor的安装及使用(一)

    step1:下载ant和YUICompressor    1) Ant:   http://ant.apache.org/bindownload.cgi   打开页面后,下拉滚动条,找到如下图所示,单 ...