MySQL之创建高性能的索引(九)

创建高性能的索引

使用索引扫描来做排序

MySQL有两种方式可以生成有序的结果:通过排序操作;或者按索引顺序扫描(MySQL有两种排序算法);如果EXPLAIN出来的type列的值为"index",则说明使用了索引扫描来做排序(不要和Extra列的"Using index")搞混淆了。扫描索引本身是很快的。因为只需要从一条索引记录移动到紧接着的下一条记录。但如果索引不能覆盖查询所需的全部列,那就不得不每扫描一条索引记录就都回表查询一次对应的行。这基本上都是随机IO,因此按索引顺序读取数据的速度通常要比顺序地全表扫描慢,尤其是在IO密集型地工作负载时。MySQL可以使用同一个索引即满足排序,又用于查找行。因此,如果可能,设计索引时应该尽可能地同时满足这两种任务,这样是最好地。只有当索引的列顺序和ORDER BY子句的顺序完全一致,并i企鹅所有列的排序方向(倒序或正序)都一样时,MySQL才能够使用索引来对结果排序。如果查询需要关联多张表,则只有当ORDER BY子句引用的字段全部为第一个表时,才能使用索引做排序。ORDER BY子句和查找型查询的限制是一样的:需要满足索引的最左前缀的要求,否则MySQL都需要执行排序操作,而无法利用索引排序。有一种情况ORDER BY子句可以不满足索引的最左前缀的要求,就是前导列为常量的时候。如果WHERE子句或者JOIN子句中对这些列指定了常量,就可以"弥补"索引的不足。
例如,Sakila示例数据库的表rental在列(rental_date,inventory_id,customer_id)上有名为rental_date的索引.(rental_date,inventory_id,customer_id):

CREATE TABLE `rental` (
....PRIMARY KEY (`rental_id`),UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`),KEY `idx_fk_inventory_id` (`inventory_id`),KEY `idx_fk_customer_id` (`customer_id`),KEY `idx_fk_staff_id` (`staff_id`),....
);

MySQL可以使用rental_date索引为下面的查询做排序,从EXPLAIN张可以看到没有出现文件排序(filesort)操作(MySQL这里称其为文件排序(filesort),其实并不一定使用磁盘文件):

mysql> EXPLAIN SELECT rental_id, staff_id FROM sakila.rental WHERE rental_date = '2005-05-25' ORDER BY inventory_id,customer_id\G
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: rentalpartitions: NULLtype: ref
possible_keys: rental_datekey: rental_datekey_len: 5ref: constrows: 1filtered: 100.00Extra: Using index condition
1 row in set, 1 warning (0.00 sec)

即使ORDER BY 子句不满足索引的最左前缀的要求,也可以用于查询排序,这是因为索引的第一列被指定为一个常数。还有更多可以使用索引做排序的查询示例。下面这个查询可以利用索引排序,是因为查询为索引的第一列提供了常量条件,而使用第二列进行排序,将两列组合在一起,就形成了索引的最左前缀:

.... WHERE rental_date = '2005-05-25' ORDER BY inventory_id DESC;

下面这个查询也没问题,因为ORDER BY 使用的两列就是索引的最左前缀:

... WHERE rental_date > '2005-05-25' ORDER BY rental_date,inventory_id;

下面是一些不能使用索引做排序的查询:

  • 1.下面这个查询使用了两种不同的排序方向,但是索引列都是正序排序的
... WHERE rental_date = '2005-05-25' ORDER BY inventory_id DESC,customer_id ASC;
  • 2.下面这个查询的ORDER BY 子句中引用了一个不在索引中的列:
... WHERE rental_date = '2005-05-25' ORDER BY inventory_id,staff_id;
  • 3.下面这个查询的WHERE和ORDER BY中的列无法组合成索引的最左前缀:
... WHERE rental_date = '2025-05-25' ORDER BY customer_id;
  • 4.下面这个查询在索引列的第一个列上是范围查询,所以MySQL无法使用索引的其余列:
... WHERE rental_date > '2005-05-25' ORDER BY inventory_id, customer_id;
  • 5.这个查询在inventory_id列上有多个等于条件,对于排序来说,这也是一种范围查询:
... WHERE rental_date='2005-05-25' AND inventory_id IN (1,2) ORDER BY customer_id;

下面这个例子理论上是可以使用索引进行关联排序的,但由于优化器在优化时将film_acotr表当作关联的第二张表,所以实际上无法使用索引:

mysql> EXPLAIN SELECT actor_id,title FROM sakila.film_actor INNER JOIN sakila.film USING(film_id) ORDER BY actor_id\G
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: filmpartitions: NULLtype: index
possible_keys: PRIMARYkey: idx_titlekey_len: 514ref: NULLrows: 1000filtered: 100.00Extra: Using index; Using temporary; Using filesort
*************************** 2. row ***************************id: 1select_type: SIMPLEtable: film_actorpartitions: NULLtype: ref
possible_keys: idx_fk_film_idkey: idx_fk_film_idkey_len: 2ref: sakila.film.film_idrows: 5filtered: 100.00Extra: Using index
2 rows in set, 1 warning (0.00 sec)

使用索引做排序的一个最重要的用法是查询同时有ORDER BY 和LIMIT子句的时候

压缩(前缀压缩)索引

MyISAM使用前缀压缩来减少索引的大小,从而让更多的索引可以放入内存中,这在某些情况下能极大地提高性能。默认只压缩字符串,但通过参数设置也可以对整数做压缩。MyISAM压缩每个索引块的方法是,先完全保存索引块中的第一个值,然后将其他值和第一个值进行比较得到相同前缀的字节数和剩余不同后缀部分,把这部分存储起来即可。例如,索引块中的第一个值是"perform",第二个值是"performance",那么第二个值得前缀压缩后存储得是类似"7,ance"这样的形式。MyISAM对行指针也采用类似的压缩方式。
压缩块使用更少的空间,代价是某些操作可能更慢,因为每个值得压缩前缀都依赖前面的值,所以MyISAM查找时无法在索引块使用二分查找而只能从头开始扫描。正序的扫描速度还不错,但是如果时倒序扫描——例如ORDER BY DESC——就不是很好了,所有在块中查找某一行的操作平均都需要扫描半个索引块。
测试表明,对于CPU密集型应用,因为扫描需要随机查找,压缩索引使得MyISAM在索引查找上要慢好几倍。压缩索引的倒序扫描就更慢了。压缩索引需要在CPU内存资源与磁盘之间做权衡。压缩索引可能只需要十分之一大小的磁盘空间,如果时IO密集型应用,对某些查询带来的好处会比成本多很多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/847006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么控制员工电脑的文件外发,六个控制文件外发的小窍门你必须了解

控制员工电脑的文件外发是企业信息安全管理中的重要环节,旨在防止敏感数据泄露、保护知识产权和维护商业秘密。 企业可以通过多种技术和管理措施相结合的方式来达到这一目的,确保既有效控制文件外发风险,又不影响正常的业务运作和员工工作效…

排序题目:删除某些元素后的数组均值

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题:删除某些元素后的数组均值 出处:1619. 删除某些元素后的数组均值 难度 2 级 题目描述 要求 给定一个整数数组 arr \texttt{arr} arr&…

文献阅读:GCNG:用于从空间转录组数据推断基因相互作用的图卷积网络

文献介绍 「文献题目」 GCNG: graph convolutional networks for inferring gene interaction from spatial transcriptomics data 「研究团队」 Ziv Bar-Joseph(美国卡内基梅隆大学) 「发表时间」 2020-12-10 「发表期刊」 Genome Biology 「影响因子…

python 贪心算法(Greedy Algo)

贪婪是一种算法范式,它逐步构建解决方案,始终选择提供最明显和直接收益的下一个部分。贪婪算法用于解决优化问题。 如果问题具有以下属性,则可以使用贪心法解决优化问题: 每一步,我们都可以做出当前看来最好的选择&…

Python模块之Pandas(三)-- DataFrame 查看形状和部分数据

查看数据框的形状: import pandas as pd data pd.read_csv("D:/my_data/data1.csv")print(data的形状为:, data.shape) 查看数据前10行: data.head(10) #查看数据前10行 查看数据后10行: data.tail(10) 查看数据某几列/某几…

3d网渲100比本地渲染快吗?渲染100邀请码1a12

3D网渲是一种基于云计算的技术,它将渲染工作交由云端进行,以网渲平台渲染100为例,比起本地渲染,它有以下一些优势。 1、本地渲染受硬件限制,只能一台电脑渲染一张图,而渲染100有充足的服务器数量&#xf…

Unity中的Surface Effector 2D组件

Surface Effector 2D 是 Unity 中 2D 物理引擎提供的一个组件,用于影响与其接触的 2D 对象的运动。它可以对碰撞到其表面的物体施加速度和力,从而改变这些物体的运动行为。下面是一些关于 Surface Effector 2D 的关键点: 主要属性 Speed&am…

QT 音乐播放器【一】 显示音频级别指示器

文章目录 效果图概述代码总结 效果图 概述 QMediaPlayer就不介绍了,就提供了一个用于播放音频和视频的媒体播放器 QAudioProbe 它提供了一个探针,用于监控音频流。当音频流被捕获或播放时,QAudioProbe 可以接收到音频数据。这个类在需要访问…

如何选择采购管理软件解决方案:推荐与指南

选择一款合适自身企业采购模式的管理软件对于企业来说至关重要。一款好的采购管理软件不仅能够提高采购效率,还能降低采购成本、优化库存管理、增强供应链的透明度和可控性。而在选择采购管理软件时,大家还需要考虑以下几个关键因素: 一、需…

代码随想录训练营Day56:Leetcode647、516

Leetcode647: 问题描述: 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 示例 1: 输入:s &q…

C/C++动态内存管理(new与delete)

目录 1. 一图搞懂C/C的内存分布 2. 存在动态内存分配的原因 3. C语言中的动态内存管理方式 4. C内存管理方式 4.1 new/delete操作内置类型 4.2 new/delete操作自定义类型 1. 一图搞懂C/C的内存分布 说明: 1. 栈区(stack):在…

前端开发三大主流框架解析

Web前端三大主流框架分别是Angular、React和Vue.js。以下是《优联前端》关于这三个框架解析介绍: Angular: 来源与开发者:Angular是由Google开发的前端框架。功能特点:Angular是一个完整的框架,包括了数据绑定、组件化…

计组雨课堂(5)知识点总结——备考期末复习(xju)

在汇编语言源程序中,“微指令语句"不是常见的组成部分,因为微指令通常是在硬件层面进行处理的,而不是在汇编语言层面。因此,不属于汇编语言源程序的是"微指令语句”。在汇编语言中,组成指令语句和伪指令语句…

直方图滤波、粒子滤波、卡尔曼滤波

三者都是基于贝叶斯滤波。 粒子滤波和直方图滤波不要求高斯分布,可解决非线性 卡尔曼滤波要求高斯分布且线性。扩展卡尔曼滤波为了解决非线性问题,利用泰勒展开进行一阶近似。 直方图滤波就是贝叶斯滤波的直观实现。自动驾驶定位算法-直方图滤波(Hist…

什么是SpringCloud? --学习笔记

什么是SpringCloud? 想象一下,你要建一个现代化城市,这个城市由很多小区组成,每个小区承担着不同的职能,比如居住、购物、娱乐、教育等。在这个城市中,小区之间需要互相沟通协作,确保整个城市的…

【Linux终端探险】:从入门到熟练,玩转基础命令的秘密(二)

文章目录 🚀Linux基础命令(二)🌈1. 寻找目录/文件命令⭐2. 创建文件命令👊3. 网络接口查询命令❤️4. 打包命令💥5. 解压命令 上期回顾: 🔥🔥🔥【Linux终端探…

python 批量ts合并成一个mp4

首先,确保你已经安装了ffmpeg。 然后再次保证所有ts文件放在同一个文件夹中,并且依次命名为 1.ts 、 2.ts 、 3.ts 、 4.ts 、 4.ts 。。。 Python完整代码如下:(ffmpeg_batch_merge_ts.py文件) #!/usr/bin/python3 # -*- coding: UTF-8 -*…

19、matlab信号预处理中的中值滤波(medfilt1()函数)和萨维茨基-戈雷滤波滤(sgolayfilt()函数)

1、中值滤波:medfilt1()函数 说明:一维中值滤波 1)语法 语法1:y medfilt1(x) 将输入向量x应用3阶一维中值滤波器。 语法2:y medfilt1(x,n) 将一个n阶一维中值滤波器应用于x。 语法3:y medfilt1(x,n…

2024年项目任务管理软件大盘点:12款值得一试的主流工具

12款优秀的项目任务管理软件:PingCode、Worktile、AIrTable、ClickUp、Teambition、Asana、Todoist、TAPD、Monday.com、Notion、Microsoft Project、Trello。 任务管理软件对于生活繁忙的人来说极为重要。它帮助用户有效跟踪他们需要完成的各项任务,包括…

mysql执行拼接的sql语句

在MySQL中,可以使用 CONCAT() 函数来拼接SQL语句。但是,请注意,直接拼接SQL语句可能会导致SQL注入问题,因此应当使用参数化查询来避免这个问题。 以下是一个使用 CONCAT() 函数拼接SQL语句的例子: SET tableName us…