mysql 松散的索引扫描(Loose index scan)

优化Group By最有效的办法是当可以直接使用索引来完全获取需要group的字段。使用这个访问方法时,MySQL使用对关键字排序的索引的类型(比如BTREE索引)。这使得索引中用于group的字段不必完全涵盖WHERE条件中索引对应的key。由于只包含索引中关键字的一部分,因此称为松散的索引扫描。

历史上MySQL不能做松散的索引扫描,这种方式可以扫描索引的非连续部分,假定下面的例子中,在列(a,b)上有一索引,要运行下面的查询:

mysql> SELECT … FROM tbl WHERE b BETWEEN 2 AND 3;

因为索引从列a开始,但是WHERE没制定列a,MySQL将做全表扫描来消除不匹配的行。
很希望有快的方式来执行查询。某些索引结构(不是MySQL)让你定位到每个范围的开始,扫描到范围结束,然后跳到下一范围的开始。
这当然是相对简单的例子,也可以很容易通过再加一个不同的索引来达到目的。实际上,很多时候添加另一个索引不一定能解决问题。一个例子是某些查询在索引的第一个列上有范围条件在第二个列上有等价条件。
从MySQL 5.0 开始,松散索引扫描在一定条件是可能的,比如在分组查询中找到最大和最小值:

mysql> EXPLAIN SELECT actor_id, MAX(film_id)
-> FROM sakila.film_actor
-> GROUP BY actor_idG
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: film_actor
type: range
possible_keys: NULL
key: PRIMARY
key_len: 2
ref: NULL
rows: 396
Extra: Using index for group-by

在下面一些情况下是可以使用松散索引扫描的:
• 查询针对一个单表。
• GROUP BY包括索引的第1个连续部分(如果对于GROUP BY,查询有一个DISTINCT子句,则所有DISTINCT的属性指向索引开头)。
• 只使用累积函数(如果有)MIN()和MAX(),并且它们均指向相同的列。
• 索引的任何其它部分(除了那些来自查询中引用的GROUP BY)必须为常数(也就是说,必须按常量数量来引用它们),但MIN()或MAX() 函数的参数例外。

(0)

相关推荐

  • mysql 松散的索引扫描(Loose index scan)

    优化Group By最有效的办法是当可以直接使用索引来完全获取需要group的字段.使用这个访问方法时,MySQL使用对关键字排序的索引的类型(比如BTREE索引).这使得索引中用于group的字段不必完全涵盖WHERE条件中索引对应的key.由于只包含索引中关键字的一部分,因此称为松散的索引扫描. 历史上MySQL不能做松散的索引扫描,这种方式可以扫描索引的非连续部分,假定下面的例子中,在列(a,b)上有一索引,要运行下面的查询: mysql> SELECT - FROM tbl WHERE

  • 简单谈谈MySQL的loose index scan

    众所周知,InnoDB采用IOT(index organization table)即所谓的索引组织表,而叶子节点也就存放了所有的数据,这就意味着,数据总是按照某种顺序存储的.所以问题来了,如果是这样一个语句,执行起来应该是怎么样的呢?语句如下: select count(distinct a) from table1; 列a上有一个索引,那么按照简单的想法来讲,如何扫描呢?很简单,一条一条的扫描,这样一来,其实做了一次索引全扫描,效率很差.这种扫描方式会扫描到很多很多的重复的索引,这样说的话优

  • MySQL优化GROUP BY(松散索引扫描与紧凑索引扫描)

    满足GROUP BY子句的最一般的方法是扫描整个表并创建一个新的临时表,表中每个组的所有行应为连续的,然后使用该临时表来找到组并应用累积函数(如果有).在某些情况中,MySQL能够做得更好,即通过索引访问而不用创建临时表.        为GROUP BY使用索引的最重要的前提条件是所有GROUP BY列引用同一索引的属性,并且索引按顺序保存其关键字.是否用索引访问来代替临时表的使用还取决于在查询中使用了哪部分索引.为该部分指定的条件,以及选择的累积函数.        由于GROUP BY 实

  • 在SQL SERVER中导致索引查找变成索引扫描的问题分析

    SQL Server 中什么情况会导致其执行计划从索引查找(Index Seek)变成索引扫描(Index Scan)呢? 下面从几个方面结合上下文具体场景做了下测试.总结.归纳. 1:隐式转换会导致执行计划从索引查找(Index Seek)变为索引扫描(Index Scan) Implicit Conversion will cause index scan instead of index seek. While implicit conversions occur in SQL Serve

  • MySQL 使用索引扫描进行排序

    目录 安装sakila 索引扫描排序 表结构 可以使用索引扫描来做排序的情况 补足前导列 order by 中只包含一种排序 无法使用索引扫描的情况 查询条件中包含不同排序方向 查询条件中引用不在索引中的列 无法组合最左前缀时 第一列是查询范围时 where中有多个等于条件 总结 安装sakila 我们将会使用MySQL示例数据库sakila来进行sql的演示和讲解 dev.mysql.com/doc/sakila/- 索引扫描排序 MySQL有两种方式可以生成有序的结果:通过排序操作﹔或者按索

  • MySQL InnoDB 二级索引的排序示例详解

    排序问题 最近看了极客时间上 <MySQL实战45讲>,纠正了一直以来对 InnoDB 二级索引的一个理解不到位,正好把相关内容总结下. PS:本文的所有测试基于 MySQL 8.0.13 . 先把问题抛出来,下面的 SQL 所创建的表,有两个查询语句,哪个索引是非必须的? CREATE TABLE `geek` ( `a` int(11) NOT NULL, `b` int(11) NOT NULL, `c` int(11) NOT NULL, `d` int(11) NOT NULL, P

  • 为MySQL创建高性能索引

    目录 1 索引基础 1.1 索引作用 1.2 MySQL索引常用数据结构 1.2.1 B-Tree 1.2.2 B+Tree索引 1.2.3 Hash索引 2 高性能索引策略 2.1 聚簇索引与非聚簇索引 聚簇索引 非聚簇索引 2.2 前缀索引 2.3 回表 2.4 覆盖索引 2.5 索引匹配方式 2.5.1 最左匹配 2.5.2 匹配列前缀 2.5.3 匹配范围值 2.5.5 只访问索引的查询 3 索引优化最佳实践 4 索引监控 1 索引基础 1.1 索引作用 在MySQL中,查找数据时先在索

  • MySQL数据库的索引原理与慢SQL优化的5大原则

    我们知道一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,所以查询语句的优化显然是重中之重. 本文旨在以开发工程师的角度来解释数据库索引的原理和如何优化慢查询. MySQL索引原理 1.索引目的 索引的目的在于提高查询效率,可以类比字典,如果要查“mysql”这个单词,我们肯定需要定位到m字母,然后从下往下找到y字母,再找到剩下的sql.如果没有索引,那么你可能需要把所有单词看一遍才能找到你想要的,如果我

  • PostgreSQL索引扫描时为什么index only scan不返回ctid

    我们都知道在PostgreSQL中使用索引扫描时,是通过索引中存储的ctid去表中得到数据的.同时在PostgreSQL中如果要查询的列都在索引中,我们还可以使用index only scan. 既然如此,当我们在查询中用到ctid时,是否还能使用index only scan呢? 按理来说是没有问题的,例如在Oracle中: SQL> select rowid,id from t1 where id = 1; ------------------------------------------

  • 详解MySQL InnoDB的索引扩展

    索引扩展,InnoDB通过将主键列附加到每个辅助索引中来自动扩展该索引.创建如下表结构: mysql> CREATE TABLE t1 ( -> i1 INT NOT NULL DEFAULT 0, -> i2 INT NOT NULL DEFAULT 0, -> d DATE DEFAULT NULL, -> PRIMARY KEY (i1, i2), -> INDEX k_d (d) -> ) ENGINE = InnoDB; Query OK, 0 rows

随机推荐