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

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. qduoj LC的课后辅导

    描述 有一天,LC给我们出了一道题,如图: 这个图形从左到右由若干个 宽为1 高不确定 的小矩形构成,求出这个图形所包含的最大矩形面积. 输入 多组测试数据每组测试数据的第一行为n(0 <= n ...

  2. 经过强制类型转换以后,变量a, b的值分别为( )short a = 128; byte b = (byte) a;

    1.Java中用补码形式表示 2.第一位正负位,1表示负,0表示正. 3.原码:一个数的二进制表示.                  3的原码00000011   -3的 原码 10000011 4 ...

  3. JAVA (1)–第一个GUI程序 添加标题 关闭窗口 屏幕位置 导入图标

      import java.awt.*; // 可以改成 import javax.swing.*; public class FirstFrame { public static void main ...

  4. 系统编程概念(文件系统mount等函数的使用)

    挂载文件系统 #include<sys/mount.h> int mount(const char *source,const char *target,const char *fstyp ...

  5. sqler sql 转rest api 源码解析(一)应用的启动入口

    sqler sql 转rest api 的源码还是比较简单的,没有比较复杂的设计,大部分都是基于开源 模块实现的. 说明: 当前的版本为2.0,代码使用go mod 进行包管理,如果本地运行注意gol ...

  6. openresty 编译ngx_pagespeed 模块-docker 构建

    ngx_pagespeed 是一个很不错的web 优化模块,我们通过简单的配置就可以对于web页面的加载有很大的提升 ngx_pagespeed 依赖psol 模块 Dockerfile   # Do ...

  7. drone 1.0 新的定时任务界面&&构建任务支持重启

    drone 1.0 的定时任务是一个不错的功能,早期的版本是必须使用cron 表达式的 最近发布的版本支持通过配置就可以了,很方便,只是目前比较简单的,支持小时. 天.周.月.年的模式 环境准备 do ...

  8. nginx https配置——Let's Encrypt 部署和维护

    let's encrypt Let's Encrypt 的最大贡献是它的 ACME 协议,第一份全自动服务器身份验证协议,以及配套的基础设施和客户端.这是为了解决一直以来 HTTPS TLS X.50 ...

  9. Space Shooter 学习

    using UnityEngine; using System.Collections; /// <summary> /// 背景滚动 /// </summary> publi ...

  10. linux中和salt中的fqdn测试小节

    设置hosts文件和hostname文件 [root@dawn-hnyd-yd-1 ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdoma ...