mysql 啥样的索引能提高查询性能呢?

news/2025/2/25 18:38:49/文章来源:https://www.cnblogs.com/aoximin/p/18736982

前言

在前面几章中,我们知道了页里面是如何存储的,页又是如何编排的。

这样我们知道了,如何定位到页,如何定位到行了,这些对我们索引的了解非常有帮助的。

知道这些后,那么我们如何利用索引查询呢? 也就是说我们如何利用这种数据结构呢? 是不是全部的查询都能通过索引去快速解决呢?该建立怎么样的索引呢。

正文

首先我们看下基本的索引结构:

索引名字是:
idx_name_birthday_phone_number

那么也就是name、birthday、phone

比如我们这样的查询:

SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday = '1990-09-27' AND phone_num
ber = '15123983239';

那么还是很吃索引的。

我们想两件事,第一件事是我们的顺序是name、birthday、phone、主键索引。
对吧。

然后这里需要的排序规则是name、birthday、phone_num
ber完全吻合。

这种也叫做全值匹配。

那么是否只有这种全值匹配的才有用呢?

那也不是。

首先我们知道,排序规则是name、然后是birthday然后是phone_num
ber 排序。

那么这里面的排序是啥?name 是一定按照顺序排序的。

然后name birthday 是按照顺序排序的。

然后name birthday phone_number 也是按照顺序排序的。

里面其实有几套排序在里面。

那么只要是我们是按照匹配到左边的列,那么就是可以使用索引的。

SELECT * FROM person_info WHERE name = 'Ashburn' AND birthday = '1990-09-27';

比如这样。

反之,匹配不到的不行:

SELECT * FROM person_info WHERE birthday = '1990-09-27';

如果我们想使用联合索引中尽可能多的列,搜索条件中的各个列必须是联合索引中
从最左边连续的列。

然后请问这样是否可以匹配到索引呢?

SELECT * FROM person_info WHERE name LIKE 'As%';

有人会想,这个like 啊,应该是用不到索引的吧,是模糊匹配啊。

但是实际上是可以的,因为name 是有序的。

因为name 是字符串,字符串排序规则是:

  1. 先按照字符串的第一个字符进行排序。
  2. 如果第一个字符相同再按照第二个字符进行排序。
  3. 如果第二个字符相同再按照第三个字符进行排序,依此类推。

也就是说这些字符串的前n个字符,也就是前缀都是排好序的,所以对于字符串类型的索引列来说,我们只匹配
它的前缀也是可以快速定位记录的.

这里面主要是利用到As 是排好序的。

如果不是前缀,那么就用不到。

比如:

SELECT * FROM person_info WHERE name LIKE '%As%';

因为只对前缀有用,那么我们想一个问题,如果我们要查后缀匹配怎么破?

那就只能反着存储。

匹配范围值:

SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow';

如果是多列的话,比如说:

SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow' AND birthday > '1980-01-0
1';

肯定也是只能用到name这个索引,birthday 是用不上滴。

精确匹配某一列并范围匹配另外一列也是可以用到索引的,其实和上面差不多。

索引还有重要一点就是用于排序,但是排序规则一定是按照索引的顺序。

这种也可以。

SELECT * FROM person_info WHERE name = 'A' ORDER BY birthday, phone_number LIMIT 10;

因为这个时候A确定了,其实还是按照name、birthday和phone_number的规则排序的。

然后这样呢?

SELECT * FROM person_info WHERE name > 'A' ORDER BY birthday, phone_number LIMIT 10;

这样就用不到索引,因为name不固定的,那么就还是按照 birthday, phone_number进行排序的。

然后这里面顺序也需要一致的。

比如ORDER BY name,birthday, phone_number

这样是吧。

里面其实是有隐藏信息的。

ORDER BY name ASC,birthday ASC, phone_number ASC

是这样的吧。

如果你是:

ORDER BY name DES,birthday DES, phone_number DES

这样也行,这样就是往后读去就行。

如果你是这样:

ORDER BY name ASC,birthday DES, phone_number DES

这样就和原来的规则不符合。

ORDER BY name, birthday LIMIT 10

这种情况直接从索引的最左边开始往右读10行记录就可以了。

ORDER BY name DESC, birthday DESC LIMIT 10

这种情况直接从索引的最右边开始往左读10行记录就可以了。

这样对于确实很高效。

如果是:

ORDER BY name, birthday DESC LIMIT 10

这样呢?

这样是否能走索引呢?

如果走索引我们要做的事情是什么呢?

对于我的第一思考是:从索引左边找到10条然后排序。

似乎好像是这样的。

但是忽略了一个条件,如果name最小值有100个,那么就不能这样。

那么应该是更复杂一些:

  1. 找到name的最小值,然后找一下是否有10条

  2. 如果没有继续找全部name第二最小值,查看是否到了10条,以此类推。

  3. 找出来后就进行排序,然后取10条

这样挺麻烦的。

然后有些人就说,就不会使用索引了。

这也不是绝对的,我觉得如果数据非常多的时候也是可以直接使用索引的。

如果没有limit 10,那么我觉得很有可能就直接不使用索引。

因为这个索引排序没有任何意义了。

因为那么得取到最小值,然后进行排序,然后取到第二大的值然后进行排序。。。以此类推,不如直接扫描表。

WHERE子句中出现非排序使用到的索引列

SELECT * FROM person_info WHERE country = 'China' ORDER BY name LIMIT 10;

那确实排序没有意义。

同样如果:

SELECT * FROM person_info ORDER BY name, country LIMIT 10;

多了一个country的话,那么也不会用到索引,因为原来的排序没有意义,但是加了一个limit就可能用到索引。

排序一般可用于分组啥的:

SELECT name, birthday, phone_number, COUNT(*) FROM person_info GROUP BY name, birthday, ph
one_number

因为有分组的话,其实就是进行切片而已,快的很。

为什么回表比较慢呢?

SELECT * FROM person_info WHERE name > 'Asa' AND name < 'Barlow';

我们通过索引,name 进行了查询。

那么其实是很快的,因为name 本身就是有序的。

然后name 之后我们找到id,这个id可能就分布在不同的页中,那么这个读取就可能变慢了。

下一节

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

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

相关文章

06 常用损失函数介绍

在前文中我们使用的损失函数都是均方误差(MSE,Mean Squared Error),本篇介绍一些其他的损失函数形式,以及他们的不同用途。 1. 回归任务常用损失函数 1.1 均方误差(MSE, Mean Squared Error) 均方误差(MSE)是回归任务中最常用的损失函数之一,用于衡量模型预测值与真实…

啦啦啦啦啦啦啦啦啦

啦啦啦 啦啦啦啦啦啦啦啦啦 ABC221G 神秘题,将坐标轴转 \(45\),然后 bitset 优化背包,记录路径把刚刚被更新的找出来,然后 _Find_next,每个点只会记一次。 AGC050a 神秘题,想到 \(\log\),然后发现一下位置 \(x\) 走十次能到的区间是 \([1024x,1024x+1023]\),区间长度够…

破解 vLLM + DeepSeek 规模化部署的“不可能三角”

通过 FC GPU 预留实例的闲置计费功能,企业用户能在充分利用 vLLM 的强大功能的同时找到成本、性能、稳定的最佳平衡点,并保持开发和运维的高效性。无论是将 FC vLLM 函数直接对外提供服务,还是深度集成到现有系统中,或是通过 CAP 还是魔搭来简化部署,都能找到满足您业务需…

条形码编码规则全解析:从黑白条纹到数字世界的转换密码

条形码的编码规则是将字符(数字、字母等)转换为特定黑白条纹或矩阵结构的标准化方法,核心目的是让机器能够快速、准确地识别和解析信息。以下是常见条形码编码规则的简介: 一维条形码编码规则 1. ​基本原理通过不同宽度的黑白条纹​(或空格)组合表示字符。 每个字符对应…

[汽车电子/车联网] CANoe

概述:CANoe CAN 全家桶区别: CANoe vs CanalyzerCANoe和CANalyzer使用方法类似(简直可以说 相同)。 都可用于simulation,区别在于CANalyzer只能模拟单个Node,而CANoe可以同时模拟多个Node。如果入门学习了CANoe,就不用入门学习CANalyzer了。安装指南 安装 CANoeDemo on …

璞华易研PLM荣登软服之家多项榜单,PLM+AI为流程行业提供产品创新引擎

近日,国内知名软件与服务评测平台软服之家发布了多个PLM(Product Lifecycle Management,产品全生命周期管理)榜单,帮助用户了解PLM领域表现卓越的软件产品和服务。在软服之家的多项榜单中,璞华易研PLM凭借其自主研发能力与行业深耕优势,在流程行业、电子信息、装备制造等…

ELK 原理介绍及实践详解

介绍了ELK(Elasticsearch, Logstash, Kibana)在大规模日志管理中的重要性,阐述了ELK解决日志分析的挑战,如日志收集、传输、存储和分析。文章详细讲解了ELK的组成部分,包括Filebeat的工作原理、Logstash的输入、过滤和输出阶段,以及Kibana的分析和可视化功能。此外,还提…

工信部人才交流中心PostgreSQL认证考试 - 聊一下更多精彩

在数字经济高速发展的今天,数据库作为信息基础设施的核心组件,其技术自主性与人才储备已成为国家战略竞争力的关键。工业和信息化部人才交流中心(以下简称“工信人才”)推出PostgreSQL认证考试,不仅是对技术发展趋势的精准响应,更是推动信创产业生态建设、填补数据库人才缺…

单链表与单循环链表的C语言实现

单链表与单循环链表的C语言实现 目录单链表与单循环链表的C语言实现单链表的增删查改单循环链表的增删查改 单链表的增删查改 /*单链表*/#include<stdio.h> #include<stdlib.h>typedef struct Node{int data;struct Node* next; }Node;Node* initList(){Node* node…

可能是全球最快捷的修改hosts文件方式

使用快捷方式一键修改hosts文件。 下面请看VCR:其实关键的命令只有一条:powershell.exe -Command "Start-Process -FilePath notepad.exe -Verb RunAs -ArgumentList "$env:SystemRoot\system32\drivers\etc\hosts""它使用记事本以管理员权限打开位于 C:…

KUKA机器人KR70伺服电机力矩不足维修攻略

库卡机器人作为先进的工业自动化解决方案,广泛应用于各种生产线中。然而,当出现KUKA机械手伺服马达力矩不足干燥的问题时,可能会严重影响其工作效率和性能。 一、库卡机器人电机力矩不足故障的原因 1. 电机老化:随着使用时间的增加,电机内部的零部件可能会出现磨损,导致力…

S2-防护-战士Warrior-团体-大秘境-专精-天赋-配装-宏

S2毕业装--属性 急速>全能>爆击>精通 急速和全能越高越好。爆击和精通随缘。 --团本天赋(更新时间2月5日)--团本天赋代码 CkEAmidFBOBFf5oKuZ7r/WeW7YEDAAAAzMzYmZGMbzsMzMz2mZMMNzgZmBwyADbMzMwDMzDMMAAAAAAgZGAgltNADDsBLLGNmBwsFbYD --大秘天赋(更新时间2月5日)--大…