简单谈谈MySQL的loose index scan

简单谈谈MySQL的loose index scan

MySQL支持多种类型的索引扫描方法,其中一种比较特殊的方法是loose index scan。来看看loose index scan是如何工作的。

什么是loose index scan

loose index scan是一种基于索引前缀的扫描方法。所谓索引前缀,指的是索引中前面一个或多个列的值,例如索引为(a,b,c)的表,其前缀可以是(a),(a,b)或(a,b,c)。套用loose index scan的思路,只需要在索引前缀上做扫描,不需要扫描整个索引。这种方法可以减少IO操作,提高查询效率。

如何启用loose index scan呢?

严格来说,MySQL并不需要我们手动启用loose index scan。当MySQL认为该方法比其他方法更优秀,并且可行的时候,就会自动选择loose index scan扫描索引。因此,要想启用这个方法,我们需要让MySQL认为它是最好的选择。

如何让MySQL认为loose index scan是最好的选择

让MySQL选择loose index scan的前提条件是:索引前缀是包含有足够的数据的子集。如果前缀所对应的数据不是很多,那么使用loose index scan就无法跳过大量的数据,此时使用一般的全索引扫描反而会更快。

那么,如何让索引前缀包含有足够的数据呢?

这个问题的答案是:更改查询列的顺序。

假设有以下的表和索引:

CREATE TABLE t (
  a INT NOT NULL,
  b INT NOT NULL,
  c INT NOT NULL,
  d INT NOT NULL,
  PRIMARY KEY (a,b,c,d),
  INDEX idx (c,b,a,d)
);

我们按照下面的顺序查询这张表:

SELECT * FROM t WHERE c=1 AND a=2 AND d>3 AND b>4;

按照顺序c->a->d->b,该查询适合使用loose index scan方法。因为此时,索引前缀idx(c,a,d)所对应的数据,几乎包括了整个查询结果。而如果我们按照其他顺序,很可能就无法利用loose index scan,需要扫描整个索引。

再看一个例子:

SELECT * FROM t WHERE a>1 AND c<9 AND b=3;

如果我们将索引字段的顺序改成(b,c,a),那么就可以使用loose index scan技术了。

总之,如果想要使用loose index scan方法,在设计索引和写查询语句时一定要注意顺序。

示例一

现在,我们做一个简单的对比实验,看看使用loose index scan的查询和一般的查询有什么不同。

-- 执行时间:100ms
SELECT * FROM t WHERE a=1 AND b=1 AND c=1 AND d=1;

-- 执行时间:80ms
SELECT * FROM t WHERE a=1 AND b=1 AND c=1 AND d BETWEEN 0 AND 100;

前者是一般的查询,后者是加入了BETWEEN的查询。两者的查询结果可能相同,但后者可以使用loose index scan方法,明显 faster than 前者。

示例二

让我们再来模拟一个大一点的表:

CREATE TABLE t_1 (
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(50) NOT NULL,
  status INT NOT NULL,
  created_date DATE NOT NULL,
  INDEX idx_status_name (status,name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- 10w行随机数据插入
INSERT INTO t_1 (name,status,created_date) VALUES
  ('名字1',1,'2019-12-01'),
  ('名字2',0,'2019-12-02'),
  ('名字3',1,'2019-12-02'),
  ...
  ('名字99998',0,'2020-08-08'),
  ('名字99999',1,'2020-08-09'),
  ('名字10000',1,'2020-08-10');

以下是查询语句:

-- 执行时间:13ms
-- 使用loose宽度扫描
SELECT * FROM t_1 WHERE status=1 AND name>='名字1000' AND created_date>='2020-07-01';

-- 执行时间:610ms
-- 一般扫描
SELECT * FROM t_1 WHERE status=1 AND name>='名字1000' AND created_date>='2019-07-01';

两个查询条件基本一样,但第一个使用了loose index scan,查询速度明显优于第二个方法。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:简单谈谈MySQL的loose index scan - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • mysql数据库无法被其他ip访问的解决方法

    针对MySQL数据库无法被其他IP访问的问题,以下是完整的解决方法攻略: 问题描述 如果将MySQL安装在本地主机上,其他设备可能无法连接到MySQL服务器。这时候就需要进行配置,以便其他设备也能够访问MySQL数据库。 解决方法 修改MySQL配置文件 在MySQL服务器上打开配置文件 my.cnf,找到 [mysqld] 节点下的 bind-addres…

    MySQL 2023年5月18日
    00
  • MySQL事务还没提交,Canal就能读到消息了?

    【问题描述】 开发有天碰到一个很奇怪的问题,他的场景是这样子的:通过Canal来订阅MySQL的binlog, 当捕获到有数据变化时,回到数据库,反查该数据的明细,然后做进一步处理。有一次,他碰到一个诡异的现象: 1. Canal收到消息,有一条主键id=31019319的数据插入 2. 11:19:51.081, 应用程序去反查数据库,11:19:51.0…

    MySQL 2023年4月18日
    00
  • MySQL下载安装配置详细教程 附下载资源

    MySQL下载安装配置详细教程 MySQL 是一种流行的开源关系型数据库,可轻松在各种操作系统上部署和使用。本文提供了 MySQL 下载、安装和配置的详细教程,遵循以下步骤,您将能够在自己的计算机上运行 MySQL 数据库。 1. 下载 MySQL 安装包 MySQL 官方网站提供了多种不同版本和操作系统的 MySQL 安装包,你可以根据你的需要选择相应的版…

    MySQL 2023年5月18日
    00
  • MySQL 8.0:无锁可扩展的 WAL 设计

    这篇文章整理自MySQL官方文档,介绍了8.0在预写式日志上实现上的修改,观点总结如下: 在8.0以前,为了保证flush list的顺序,redo log buffer写入过程需要加锁,无法实现并行,高并发的环境中,会同时有非常多的min-transaction(mtr)需要拷贝数据到Log Buffer,如果通过锁互斥,那么毫无疑问这里将成为明显的性能瓶…

    2023年4月8日
    00
  • Mysql巧用join优化sql的方法详解

    Mysql巧用join优化sql的方法详解 什么是join 在Mysql中,join指的是基于两个或多个表之间的共同字段进行查询的方法。通过join,可以将不同表中的数据和信息结合在查询结果中,达到获取更全面的信息的目的。 如何巧用join优化sql语句 使用内联接代替子查询 在一些需要复杂查询的场景下,为了获取准确的查询结果,可能会使用子查询。然而,子查询…

    MySQL 2023年5月19日
    00
  • 详解MySQL DISTINCT:过滤重复数据

    MySQL DISTINCT是用来过滤重复数据的关键字。它对于需要在SELECT语句中查询不同值的情况非常有用。 使用MySQL DISTINCT可以根据一个或多个列选择唯一的值。如果SELECT语句中包含多个列,DISTINCT将根据这些列的组合选择唯一的组合。 语法 SELECT DISTINCT column_name(s) FROM table_na…

    MySQL 2023年3月9日
    00
  • 自动清理MySQL binlog日志

    开启MySQL binlog日志的服务器,如果不设置自动清理日志,默认binlog日志一直保留着,时间一长,服务器磁盘空间被binlog日志占满,导致MySQL数据库出错。 使用下面方法可以安全清理binlog日志 一、没有主从同步的情况下清理日志 mysql -uroot -p123456 -e ‘PURGE MASTER LOGS BEFORE DATE…

    MySQL 2023年4月13日
    00
  • 如何使用python连接mysql数据库

      首先在我们工作中,难免遇到给测试环境造大量的测试数据,给数据库造数据有很多方式方法,这里用python造数据一般是这样的:    第一步进入Linux系统里已部署好的mysql数据库登录如:/app/mysql/bin/mysql -uroot -pBccdr@123456    第二步:进入数据库后先验证数据库是否正常,比如先查询库,表等,show d…

    MySQL 2023年4月12日
    00
合作推广
合作推广
分享本页
返回顶部