MySQL 8.0 对 limit 的优化技巧

目录
  • 一、前言
  • 二、MySQL 8.0 对limit 的改进
  • 三、实践出真知
    • 3.1 默认开启参数
    • 3.2 关闭该参数
  • 四、总结

一、前言

提到 limit 优化,大多数 MySQL DBA 都不会陌生,能想到各种应对策略,比如延迟关联,书签式查询等等,之前我也写过一篇优化的文章:https://www.jb51.net/article/234357.htm ,有兴趣的朋友可以复习一下。

二、MySQL 8.0 对limit 的改进

对于 limit N 带有 group by ,order by 的 SQL 语句 (order by 和 group by 的字段有索引可以使用),MySQL 优化器会尽可能选择利用现有索引的有序性,减少排序–这看起来是 SQL 的执行计划的最优解,但是实际上效果其实是南辕北辙,相信很多 DBA 遇到的相关案例中 sql 执行计划选择 order by id 的索引进而导致全表扫描,而不是利用 where 条件中的索引查找过滤数据。MySQL 8.0.21 版本之前,并没有什么参数来控制这种行为,但是自 MySQL 8.0.21 之后提供一个优化器参数 prefer_ordering_index ,通过设置 optimizer_switch 来开启或者关闭该特性 。 比如:

SET  optimizer_switch  = "prefer_ordering_index=off";
SET  optimizer_switch = "prefer_ordering_index=on";

三、实践出真知

测试环境 MySQL 社区版 8.0.30

构造测试数据

CREATE TABLE t (
id1 BIGINT  NOT NULL  PRIMARY KEY auto_increment,
id2 BIGINT NOT NULL,
c1 VARCHAR(50) NOT NULL,
c2 varchar(50) not null,
INDEX i (id2, c1));

insert into t(id2,c1,c2) values(1,'a','xfvs'),(2,'bbbb','xfvs'),(3,'cdddd','xfvs'),(4,'dfdf','xfvs'),(12,'bbbb','xfvs'),(23,'cdddd','xfvs'),(14,'dfdf','xfvs'),
(11,'bbbb','xfvs'),(13,'cdddd','xfvs'),(44,'dfdf','xfvs'),(31,'bbbb','xfvs'),(33,'cdddd','xfvs'),(34,'dfdf','xfvs');

3.1 默认开启参数

mysql  (test) >  SELECT @@optimizer_switch LIKE '%prefer_ordering_index=on%';
+------------------------------------------------------+
| @@optimizer_switch LIKE '%prefer_ordering_index=on%' |
+------------------------------------------------------+
|                                                    1 |
+------------------------------------------------------+
1 row in set (0.00 sec)

查询非索引字段 ,id2 上有索引 ,order by 主键 id1 ,explain 查看执行计划 type index 说明使用索引扫描使用 using where 过滤结果集。这个是优化器的自以为的最优选择,但是实际上遇到数据集合比较大的表,该执行计划就不是最优解,反而导致慢查。

mysql  (test) > explain select c2 from t where id2>8 ORDER BY id1 ASC LIMIT 2\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
   partitions: NULL
         type: index
possible_keys: i
          key: PRIMARY
      key_len: 8
          ref: NULL
         rows: 2
     filtered: 69.23
        Extra: Using where
1 row in set, 1 warning (0.00 sec)

3.2 关闭该参数

mysql  (test) > SET optimizer_switch = "prefer_ordering_index=off";

mysql  (test) > explain select c2 from t where id2>8 ORDER BY id1 ASC LIMIT 2\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
   partitions: NULL
         type: range
possible_keys: i
          key: i
      key_len: 8
          ref: NULL
         rows: 9
     filtered: 100.00
        Extra: Using index condition; Using filesort
1 row in set, 1 warning (0.00 sec)

经过调整之后,查看执行计划发现优化器选择 id2 索引字段找到记录做过滤,并且使用了ICP 特性,减少物理 io 请求,而不是选择使用主键 id1 遍历索引然后回表查询。

显然 通过人为介入参数调整优化器的行为能带来更好的优化效果。

四、总结

从不同版本的 MySQL 发展轨迹来看 MySQL 的优化器越来越智能 (比如大家期待已久的直方图特性) ,能更多的减少人为干预,提升执行计划的准确性。

到此这篇关于MySQL 8.0 对 limit 的优化的文章就介绍到这了,更多相关MySQL 8.0 limit优化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 详细聊聊MySQL中的LIMIT语句

    目录 问题 server层和存储引擎层 那LIMIT是什么鬼? 怎么办? 吐个槽 最近有多个小伙伴在答疑群里问了小孩子关于LIMIT的一个问题,下边我来大致描述一下这个问题. 问题 为了故事的顺利发展,我们得先有个表: CREATE TABLE t ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, key1 VARCHAR(100), common_field VARCHAR(100), PRIMARY KEY (id), KEY idx_key1 (key1

  • 详解MySQL的limit用法和分页查询语句的性能分析

    limit用法 在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能. SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数.LIMIT 接受一个或两个数字参数.参数必须是一个整数常量.如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目.初始记

  • mysql 8.0.18 安装配置优化教程

    Mysql安装.配置.优化,供大家参考,具体内容如下 Mysql下载 首先登入官网下载mysql的安装包,官网地址https://dev.mysql.com/下拉到最后选择downloads里的 MySQL Community Server 选择所需下载的版本 MySQL安装 1.打开下载的mysql安装文件mysql-5.5.43-win32.rar,双击解压缩,运行"setup.exe". 2.选择安装类型,有"Typical(默认)"."Comple

  • 详细介绍mysql中limit与offset的用法

    目录 mysql limit与offset用法 附:Mysql limit offset用法举例 总结 有的时候我们在学习或者工作中会使用到SQL语句,那么介绍一下limit和offset的使用方法. mysql limit与offset用法 mysql里分页一般用limit来实现,例如: 1.select* from user limit 3 表示直接取前三条数据 2.select * from user limit 1,3; 表示取1后面的第2,3,4三条条数据 3.select * fro

  • MySQL8.0 索引优化invisible index详情

    目录 前言 索引使用情况测试 如何临时让优化器可以看到这个索引呢? 修改索引的可见性 前言 MySQL8.0 开始支持不可见索引. 优化器根本不使用不可见索引,但会以其他的方式正常维护. 默认情况下 索引是可见的. 通过不可见索引,可以方便数据库管理人员 检查 索引对查询性能的影响,而不会进行破坏性的更改 . 应用场景: 软删除,灰度发布 -- 创建测试表 mysql> create table t1(i int ,j int); Query OK, 0 rows affected (0.03

  • Mysql排序和分页(order by&limit)及存在的坑

    排序查询(order by) 电商中:我们想查看今天所有成交的订单,按照交易额从高到低排序,此时我们可以使用数据库中的排序功能来完成. 排序语法: select 字段名 from 表名 order by 字段1 [asc|desc],字段2 [asc|desc]; 需要排序的字段跟在order by之后: asc|desc表示排序的规则,asc:升序,desc:降序,默认为asc: 支持多个字段进行排序,多字段排序之间用逗号隔开. 单字段排序 mysql> create table test2(

  • mysql分页的limit参数简单示例

    Mysql的分页的两个参数 select * from user limit 1,2 1表示从第几条数据开始查(默认索引是0,如果写1,从第二条开始查) 2,表示这页显示几条数据 到此这篇关于mysql分页的limit参数的文章就介绍到这了,更多相关mysql分页limit参数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

  • mysql中的limit用法有哪些(推荐)

    SELECT * FROM 表名 limit m,n; SELECT * FROM table LIMIT [offset,] rows; 1.m代表从m+1条记录行开始检索,n代表取出n条数据.(m可设为0) 如:SELECT * FROM 表名 limit 6,5; 表示:从第7条记录行开始算,取出5条数据 2.值得注意的是,n可以被设置为-1,当n为-1时,表示从m+1行开始检索,直到取出最后一条数据. 如:SELECT * FROM 表名 limit 6,-1; 表示:取出第6条记录行以

  • MySQL 8.0 对 limit 的优化技巧

    目录 一.前言 二.MySQL 8.0 对limit 的改进 三.实践出真知 3.1 默认开启参数 3.2 关闭该参数 四.总结 一.前言 提到 limit 优化,大多数 MySQL DBA 都不会陌生,能想到各种应对策略,比如延迟关联,书签式查询等等,之前我也写过一篇优化的文章:https://www.jb51.net/article/234357.htm ,有兴趣的朋友可以复习一下. 二.MySQL 8.0 对limit 的改进 对于 limit N 带有 group by ,order b

  • Mysql根据时间查询日期的优化技巧

    例如查询昨日新注册用户,写法有如下两种: EXPLAIN select * from chess_user u where DATE_FORMAT(u.register_time,'%Y-%m-%d')='2018-01-25'; EXPLAIN select * from chess_user u where u.register_time BETWEEN '2018-01-25 00:00:00' and '2018-01-25 23:59:59'; register_time字段是date

  • Mysql优化技巧之Limit查询的优化分析

    前言 在实际业务中对于分页来说是一个比较常见的业务需求.那么就会使用到limit查询,当我们在使用Limit查询的时候,在数据比较小.或者只查询前面一部分数据的时候效率是很高的.但是当数据量大的时候,或者查询offset数量比较大的时候,如:limit 100000,20效率往往就不尽人意了.通常的一个办法就是Limit配合order by,如果order by有对用户的索引的话,效率通常是比较不错的. 对于这种情况,最简单的查询就是 使用覆盖索引,查询某些需要的列.这样的效果是很好的 如下面这

  • MySQL数据库十大优化技巧

    1.优化你的MySQL查询缓存 在MySQL服务器上进行查询,可以启用高速查询缓存.让数据库引擎在后台悄悄的处理是提高性能的最有效方法之一.当同一个查询被执行多次时,如果结果是从缓存中提取,那是相当快的. 但主要的问题是,它是那么容易被隐藏起来以至于我们大多数程序员会忽略它.在有些处理任务中,我们实际上是可以阻止查询缓存工作的. 复制代码 代码如下: // query cache does NOT work $r = mysql_query("SELECT username FROM user

  • 101个MySQL优化技巧和提示

    MySQL是一个功能强大的开源数据库.随着越来越多的数据库驱动的应用程序,人们一直在推动MySQL发展到它的极限.这里是101条调节和优化MySQL安装的技巧.一些技巧是针对特定的安装环境的,但这些思路是通用的.我已经把他们分成几类,来帮助你掌握更多MySQL的调节和优化技巧. MySQL 服务器硬件和操作系统调节: 1. 拥有足够的物理内存来把整个InnoDB文件加载到内存中--在内存中访问文件时的速度要比在硬盘中访问时快的多. 2. 不惜一切代价避免使用Swap交换分区 – 交换时是从硬盘读

  • 分享101个MySQL调试与优化技巧

    MySQL是一个功能强大的开源数据库.随着越来越多的数据库驱动的应用程序,人们一直在推动MySQL发展到它的极限.这里是101条调节和优化MySQL安装的技巧.一些技巧是针对特定的安装环境的,但这些思路是通用的.我已经把他们分成几类,来帮助你掌握更多MySQL的调节和优化技巧. MySQL 服务器硬件和操作系统调节: 1. 拥有足够的物理内存来把整个InnoDB文件加载到内存中--在内存中访问文件时的速度要比在硬盘中访问时快的多. 2. 不惜一切代价避免使用Swap交换分区 – 交换时是从硬盘读

  • Mysql查询语句优化技巧

    索引优化,查询优化,查询缓存,服务器设置优化,操作系统和硬件优化,应用层面优化(web服务器,缓存)等等.这里的记录的优化技巧更适用于开发人员,都是从网络上收集和自己整理的,主要是查询语句上面的优化,其它层面的优化技巧在此不做记录. 查询的开销指标: 执行时间 检查的行数 返回的行数 建立索引的几个准则: (1).合理的建立索引能够加速数据读取效率,不合理的建立索引反而会拖慢数据库的响应速度. (2).索引越多,更新数据的速度越慢. (3).尽量在采用MyIsam作为引擎的时候使用索引(因为My

  • 提升MYSQL查询效率的10个SQL语句优化技巧

    MySQL数据库执行效率对程序的执行速度有很大的影响,有效的处理优化数据库是非常有用的.尤其是大量数据需要处理的时候. 1. 优化你的MySQL查询缓存 在MySQL服务器上进行查询,可以启用高速查询缓存.让数据库引擎在后台悄悄的处理是提高性能的最有效方法之一.当同一个查询被执行多次时,如果结果是从缓存中提取,那是相当快的. 但主要的问题是,它是那么容易被隐藏起来以至于我们大多数程序员会忽略它.在有些处理任务中,我们实际上是可以阻止查询缓存工作的. // query cache does NOT

  • php导入大量数据到mysql性能优化技巧

    本文实例讲述了php导入大量数据到mysql性能优化技巧.分享给大家供大家参考.具体分析如下: 在mysql中我们结合php把一些文件导入到mysql中,这里就来分享一下我对15000条记录进行导入时分析与优化,需要的朋友可以参考一下. 之前有几篇文章,说了最近tiandi在帮朋友做一个小项目,用于统计电话号码的,每次按需求从数据库里随机生成打包的电话号码,然后不停地让人打这些电话号码推销产品(小小鄙视一下这样的行为).但是朋友要求帮忙,咱也不能不帮啊,是吧.程序两个星期前已经做好,测试完毕交工

随机推荐