优化嵌套查询

嵌套查询(子查询)可以使用SELECT语句来创建一个单列的查询结果,然后把这个结果作为过滤条件用在另一个查询中。嵌套查询写起来简单,也容易理解。但是,有时候可以被更有效率的连接(JOIN)替代。

现在假如要找出从来没有在网站中消费的客户,也就是查询在客户customer表中但是不在支付payment表中的客户信息。

嵌套查询:

explain select * from customer where customer_id not in (select customer_id from payment);

连接改写:

explain select * from customer a left join payment b on a.customer_id = b.customer_id where b.customer_id is null;

画外音:连接查询效率更高的原因,是因为MySQL不需要在内存中创建临时表来完成这个逻辑上需要两个步骤的查询工作;并且Not exists表示MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行, 就不再搜索了。

优化分页查询

在MySQL中做分页查询,MySQL 并不是跳过 offset 行,而是取 offset+N 行,然后返回放弃前 offset 行,返回 N 行,那当 offset 特别大的时候,效率就非常的低下。例如“limit 1000,20”,此时MySQL排序出前1020条数据后仅仅需要第1001到1020条记录,前1000条数据都会被抛弃,查询和排序的代价非常高。由此可见MySQL的分页处理并不是十分完美,需要我们在分页SQL上做一些优化,要么控制返回的总页数,要么对超过特定阈值的页数进行 SQL 改写

画外音:控制返回的总页数并不是那么靠谱,毕竟每页的数据量也不能过大,数据多起来之后,控制返回的总页数就变的不现实了。所以还是要对超过特定阈值的页数进行 SQL 改写

现在假设要对电影表film排序后取某一页数据

explain select * from film order by title limit 50,5;

可以看到优化器实际上做了全表扫描,处理效率不高。

第一种优化思路

在索引上完成排序分页的操作,最后根据主键关联回表查询所需要的其他列内容。

画外音:此处涉及到了SQL优化的两个重要概念,索引覆盖和回表,我在前面的文章中详细介绍过这两个概念。通过索引覆盖在索引上完成扫描和排序(索引有序),最后通过主键(InnoDB引擎索引会通过主键回表)回表查询,最大限度减少回表查询的I/O次数。

explain select * from film a inner join (select film_id from film order by title limit 50,5)b on a.film_id = b.film_id;

第二种优化思路

把LIMIT查询转换成某个位置的查询,减少分页翻页的压力。

假设现在每页10条数据,要取第42页的数据。

explain select * from film order by title limit 410,10;

现在需要多传一个参数,就是上一页(第41页)的最后一条数据的主题title,

SQL可以改写为:

explain select * from film where title>'HOLES BRANNIGAN' order by title limit 10;

这样就把LIMIT m,n 转换成了LIMIT n的查询,但是这种方案只适合在不会出现重复值的特定环境,否则分页结果可能会丢失数据。

总结

对于嵌套查询和分页查询的优化,归根结底就是遵循SQL优化原则之一——减少回表查询的I/O次数。对于分页查询优化,更建议使用第一种优化方案,性能更好,稳定性更高。

参考

《深入浅出MySQL》

作者:CoderFocus

微信公众号:

声明:本文为博主学习感悟总结,水平有限,如果不当,欢迎指正。如果您认为还不错,不妨点击一下下方的【推荐】按钮,谢谢支持。转载与引用请注明作者及出处。

MySQL——优化嵌套查询和分页查询的更多相关文章

  1. SQL语句or查询,union all查询,分页查询,分组,AND查询

    一.OR查询 1.在AND多个筛选条件和一个or条件时,如果没有括号包裹,or会就近原则包裹之后的所有and条件,也就是同级的多个and条件只能对,or条件的一边起作用 2.如果or条件两边的筛选条件 ...

  2. SQL Server -- 回忆笔记(四):case函数,索引,子查询,分页查询,视图,存储过程

    SQL Server知识点回忆篇(四):case函数,索引,子查询,分页查询,视图,存储过程 1. CASE函数(相当于C#中的Switch) then '未成年人' else '成年人' end f ...

  3. Linq高级查询,分页查询及查询分页结合

    一.高级查询与分页查询 1.以...开头    StartsWith Repeater1.DataSource=con.Users.Where(r=>r.Nickname.StartsWith( ...

  4. Mysql系列(五)—— 分页查询及问题优化

    一.用法 在Mysql中分页查询使用关键字limit.limit的语法如下: SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15 limit关键字带有 ...

  5. MySQL 百万级数据量分页查询方法及其优化

    方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N 适应场景: 适用于数据量较少的情况(元组百/千级) 原因/缺 ...

  6. mysql limit查询(分页查询)探究

    MySQL的Limit子句 LIMIT offset,length Limit子句可以被用于强制 SELECT 语句返回指定的记录数.Limit接受一个或两个数字参数.参数必须是一个整数常量.如果给定 ...

  7. MYSQL优化派生表(子查询)在From语句中的

    Mysql 在5.6.3中,优化器更有效率地处理派生表(在from语句中的子查询): 优化器推迟物化子查询在from语句中的子查询,知道子查询的内容在查询正真执行需要时,才开始物化.这一举措提高了性能 ...

  8. mysql优化---订单查询优化:异步分页处理

    订单分页查询: 老的代码是顺序执行查询数据和计算总记录数,但是如果条件复杂的话(比如关联子表)查询的时间要超过20s种 public static PagedList<Map<String ...

  9. Oracle子查询相关内容(包含TOP-N查询和分页查询)

    本节介绍Oracle子查询的相关内容: 实例用到的数据为oracle中scott用户下的emp员工表,dept部门表,数据如下: 一.子查询 1.概念:嵌入在一个查询中的另一个查询语句,也就是说一个查 ...

随机推荐

  1. OpenCL科普及在ubuntu 16.04 LTS上的安装

    OpenCL(Open Computing Language,开放计算语言)是一个为异构平台编写程序的框架,此异构平台可由CPU.GPU.DSP.FPGA或其他类型的处理器與硬體加速器所组成.Open ...

  2. I2C软件调试思路并知识总结

    I2C是一种只使用两根线的串行通信协议.一根线是串行数据线SDA,另外一种是串行时钟线SCL. I²C允许相当大的工作电压范围,但典型的电压准位为+3.3V或+5v. I²C的参考设计使用一个7比特长 ...

  3. 【LeetCode】13. 罗马数字转整数

    题目 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如, 罗马数字 2 写做 II ,即为 ...

  4. python学习记录(一)

    1.打印操作 >>> print('hello') hello >>> print(1+2) 3 2.字符串操作 ① ') Traceback (most rece ...

  5. java面试题:当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

    答:是值传递.Java编程语言只有值传递参数. 当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本.指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用 ...

  6. Linux_CentOS-服务器搭建 <一>

    本人CentOS版本6.3 必备的两个小软件: 安装PUTTY远程控制linux的非常小但非常好用的小工具. 安装WINSCP,使用ssh实现我windows上和linux服务器上文件的互传. 呵呵, ...

  7. CSS 基础:HTML 标记与文档结构(1)<思维导图>

    这段时间利用一下间隙时间学习了CSS的基础知识,主要目的是加深对CSS的理解,虽然个人主要工作基本都是后台开发,但是个人觉得系统学习一下CSS的基础还是很有必要的.下面我学习CSS时做的思维导图(全屏 ...

  8. 11个教程中不常被提及的JavaScript小技巧

    这次我们主要来分享11个在日常教程中不常被提及的JavaScript小技巧,他们往往在我们的日常工作中经常出现,但是我们又很容易忽略. 1.过滤唯一值 Set类型是在ES6中新增的,它类似于数组,但是 ...

  9. PHP四大基本排序算法实例

    PHP四大基本排序算法包括:冒泡排序法,快速排序法,选择排序法,插入排序法. 1. 冒泡排序 思路分析:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往 ...

  10. MySQL常用的备份方式与备份工具简介

    一.MySQL备份方式与备份类型 1.备份的必要性 再生产环境中,为了防止硬件故障.软件故障.自然灾害.误操作等各种原因导致的数据库数据丢失后能恢复到事故之前的状态,我们需要对数据库进行备份和恢复操作 ...