Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >关于MySQL索引选择,先看看这十条建议

关于MySQL索引选择,先看看这十条建议

原创
作者头像
windealli
发布于 2024-03-06 12:44:28
发布于 2024-03-06 12:44:28
81300
代码可运行
举报
文章被收录于专栏:windealliwindealli
运行总次数:0
代码可运行

1. 根据查询频率选择索引

如果某个字段在查询中经常被用作过滤条件,那么在这个字段上创建索引可能会提高查询性能。例如,如果你经常根据员工的姓氏查询,那么在姓氏字段上创建索引可能是有益的。

示例:

假设电商系统的商品表(products)包含下面的列

product_id

product_name

price

description

1

Product A

100

This is a great product A.

2

Product B

200

This is a great product B.

3

Product C

300

This is a great product C.

...

...

...

...

商品名称(product_name)和价格(price)列可能会经常被作为查询条件,因而适合创建索引,但是描述列(description)可能不适合创建索引。

2. 根据数据唯一性选择索引

如果表中的某个字段包含唯一值(例如,员工ID或社会保障号),那么在这个字段上创建索引可能会提高查询性能。唯一索引不仅可以提高查询性能,还可以防止插入重复的数据。

示例:

当然可以,以下是一个用户表的示例:

user_id

user_name

gender

1

anne

Female

2

windeal

Male

3

lipl

Male

在这个用户表中,user_iduser_name都可以作为索引,因为它们都具有唯一性。

gender不适合作为索引,因为它的值可能不是唯一的(即有多个用户可能都是"Male"或"Female")。在大多数情况下,索引应该是唯一的,以便快速有效地查找特定的记录。

3. 根据数据分布和查询范围选择索引

如果表中的数据分布不均匀,或者查询通常涉及到数据的一个小范围,那么在这个范围内的字段上创建索引可能会提高查询性能。

示例:

例如,你有一个订单信息表,如果你经常查询过去一周的订单,那么在订单日期字段上创建索引可能是有益的。

order_id

customer_id

product_id

order_date

1

101

201

2022-01-01

2

102

202

2022-01-02

3

103

203

2022-01-03

4

104

204

2022-01-04

5

105

205

2022-01-05

在这个表中,如果你的查询通常涉及到最近的订单(例如,"查找过去一周的所有订单"),那么在order_date字段上创建索引可能会提高查询性能。

创建索引后,数据库可以快速定位到特定日期范围的订单,而不需要扫描整个表。这对于大型表来说尤其重要,因为全表扫描可能会非常耗时。

4. 使用短索引

如果可能,应该使用短索引,尽量选择数据类型小的列作为索引。

例如,选择INT而不是VARCHAR。因为数据类型小的列,索引的大小就小,查询速度就快。

这是因为数据库对短索引的搜索速度更快,而且短索引占用的磁盘空间也更少。

示例:

以下是一个员工表的示例:

employee_id

employee_name

birth_date

1

windeal

1990-01-01

2

lipl

1991-02-02

3

anne

1992-03-03

4

jane

1993-04-04

在这个表中,如果你经常需要根据员工ID(employee_id)或员工姓名(employee_name)来查找员工,那么你可能会考虑在这两个字段上创建索引。

然而,employee_id是一个整数字段,而employee_name是一个字符串字段。整数字段通常占用的空间比字符串字段少,因此在employee_id上创建索引可能会更有效。这个索引会占用更少的磁盘空间,而且查询速度也可能更快。

请注意,这并不意味着你永远不应该在字符串字段上创建索引。如果你的应用经常需要根据员工姓名来查找员工,那么在employee_name上创建索引可能仍然是有益的。你应该根据你的应用的实际需求来选择索引。

5. 利用前缀索引

如果某个字符串列的前几个字符已经足够区分大部分值,那么就可以只对这个列的前缀部分建立索引,而不是整个字符串。这样可以减少索引的大小,提高查询速度。

示例:

以下是一个员工表的示例:

employee_id

employee_addr

1

GuangDong.ShenZhen.FuTian

2

ZheJiang.HangZhou.XiHu

3

JiangSu.NanJing.JianYe

4

SiChuan.ChengDu.JinNiu

在这个表中,employee_addr字段是一个字符串字段,可能会很长。如果你经常需要根据员工的地址来查找员工,那么你可能会考虑在这个字段上创建索引。

然而,如果地址的前几个字符已经足够区分大部分员工,那么你可以只对这个字段的前缀部分创建索引。例如,你可以创建一个只包含前10个字符的前缀索引。

MySQL中,你可以使用以下语句创建前缀索引:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE INDEX idx_employee_addr ON employees (employee_addr(10));

这个索引会占用更少的磁盘空间,而且查询速度也可能更快。然而,这种方法的缺点是,如果你需要根据地址的后半部分来查找员工,那么这个索引可能就不太有用了。你应该根据你的应用的实际需求来选择索引。

6. 多列索引(联合索引)

如果经常需要通过多个列来进行查询,那么可以考虑创建多列索引。但是要注意,多列索引并不等于多个单列索引。

假设我们有一个名为 orders 的表,它有 customer_id 和 order_date 两个列。如果我们经常需要通过 customer_id 和 order_date 来查询数据,那么我们可以创建一个多列索引。

在 SQL 中,创建多列索引的语法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE INDEX idx_orders_on_customer_id_and_order_date 
ON orders (customer_id, order_date);

这将创建一个名为 idx_orders_on_customer_id_and_order_date 的索引,它基于 orders 表的 customer_id 和 order_date 列。

然而,这并不等于创建了两个单列索引,一个基于 customer_id,另一个基于 order_date。多列索引是基于列值的组合进行索引的。

例如,

  • 如果你有一个查询是这样的: SELECT * FROM orders WHERE customer_id = 1 AND order_date = '2020-01-01'; 这个查询将能够利用我们创建的多列索引。
  • 如果你的查询只涉及到其中一个列,例如: SELECT * FROM orders WHERE customer_id = 1; 那么这个查询只能利用到 customer_id 的部分索引。
  • 如果你的查询只涉及到 order_date,例如: SELECT * FROM orders WHERE order_date = '2020-01-01'; 那么这个查询将无法利用我们创建的多列索引,因为多列索引是按照列的顺序来建立的,order_date 是索引中的第二列,不能单独被利用。

7. 外键索引

在外键上创建索引可以加快JOIN操作的速度。

假设我们有两个表,orders 和 customers,其中 orders 表有一个 customer_id 列,这是 customers 表的外键。

在 SQL 中,我们可以在 customer_id 列上创建一个索引,以加快 JOIN 操作的速度。创建索引的语法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE INDEX idx_orders_on_customer_id ON orders (customer_id);

这将创建一个名为 idx_orders_on_customer_id 的索引,它基于 orders 表的 customer_id 列。

现在,当我们执行以下 JOIN 操作时:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT * FROM orders JOIN customers ON orders.customer_id = customers.id;

数据库可以使用 idx_orders_on_customer_id 索引来快速找到匹配的行,从而加快 JOIN 操作的速度。

8. 考虑索引的排序

索引的排序顺序会影响查询的性能。例如,如果你经常执行范围查询(如WHERE column BETWEEN value1 AND value2),那么应该选择能够在这个范围内提供最快搜索速度的排序顺序。

假设我们有一个 orders 表,其中有一个 order_date 列。如果我们经常需要查询在特定日期范围内的订单,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SELECT * FROM orders WHERE order_date BETWEEN '2020-01-01' AND '2020-12-31';

那么我们可以在 order_date 列上创建一个索引,并选择一个能够在这个日期范围内提供最快搜索速度的排序顺序。在大多数数据库系统中,日期类型的列通常默认按照升序排序,这对于日期范围查询来说是最有效的。

创建索引的 SQL 语句如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE INDEX idx_orders_on_order_date ON orders (order_date);

这将创建一个名为 idx_orders_on_order_date 的索引,它基于 orders 表的 order_date 列,并默认按照升序排序。

现在,当我们执行上述的日期范围查询时,数据库可以使用 idx_orders_on_order_date 索引来快速找到在指定日期范围内的订单,从而提高查询的性能。

9. 避免过度索引

每个额外的索引都会占用额外的磁盘空间,并且在插入和更新数据时需要额外的时间来维护索引。因此,应该避免对不经常用于搜索或排序的列进行索引。

10. 避免在频繁更新的列上建立索引

如果一个列的值经常变化,那么每次值变化都需要更新索引,这将导致数据库的性能下降。因此,尽量避免在更新频率高的列上建立索引。

示例:

假设我们有一个 users 表,其中有一个 last_login 列,这个列记录了用户最后一次登录的时间。这个列的值可能会经常变化,因为每次用户登录时,都会更新这个列的值。

在这种情况下,如果我们在 last_login 列上创建一个索引,那么每次用户登录时,都需要更新这个索引。这将导致数据库的性能下降,因为更新索引是一个相对耗时的操作。

因此,尽管在 last_login 列上创建一个索引可能会加快某些查询的速度(例如,查找最近登录的用户),但由于这个列的值经常变化,所以最好避免在这个列上创建索引。

以下是在 last_login 列上创建索引的 SQL 语句,但是我们通常不推荐这样做:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE INDEX idx_users_on_last_login ON users (last_login);

相反,我们应该考虑在其他不太可能经常变化的列上创建索引,例如 email 或 username 列。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
SQL索引失效原因分析与解决方案
原因: 该查询中使用了 customer_id 列,但如果没有为该列建立索引,数据库可能会选择进行全表扫描,而不是利用索引进行快速查询。
GeekLiHua
2025/01/21
1020
【收藏】MySQL 超全优化清单(可执行系列)
先从一般的语句优化开始,其实对于很多规范大家并不陌生,可就是在用的时候,无法遵从,希望今天大家再过一遍,可以养成一种良好的数据库编码习惯。
lyb-geek
2024/07/17
2700
【收藏】MySQL 超全优化清单(可执行系列)
日常开发常见MySQL性能优化策略及应用场景
在电子商务平台的日常运营中,经常需要根据用户的订单状态和日期进行查询。随着订单量的增加,查询响应时间变长,影响报表生成和订单处理效率。
GeekLiHua
2024/08/19
2400
日常开发常见MySQL性能优化策略及应用场景
PostgreSQL亿级行数据处理
使用Timescale压缩和分块跳过索引,实现PostgreSQL处理数十亿行数据的方法。
云云众生s
2025/01/12
1780
PostgreSQL亿级行数据处理
五大SQL优化技巧,助你轻松提升数据库查询效率
提升SQL生产力是数据库管理和优化的关键。以下是五个关键技巧,每个技巧都配有具体应用场景、案例代码以及使用前后的性能对比。
老表
2024/07/11
5350
五大SQL优化技巧,助你轻松提升数据库查询效率
MySQL索引优化分析「建议收藏」
为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字段的意义。助你了解索引,分析索引,使用索引,从而写出更高性能的sql语句。还在等啥子?撸起袖子就是干!
全栈程序员站长
2022/07/12
8230
MySQL索引优化分析「建议收藏」
深入解析MySQL索引:本质、分类、选择及使用原则
索引,作为数据库中的一种核心数据结构,其本质在于通过改变数据结构来加快查询效率。可以将索引理解为数据库中的一种“目录”或“路标”,它帮助数据库系统快速定位到需要查询的数据行,从而大大提高数据检索的速度。索引的本质就是一张特殊的表,前面是索引的关键字,后面是这个关键字存放的地址。当数据量庞大时,查找索引比查找全部内容要快得多,而且索引表数据量小,非常节省计算机资源。
小马哥学JAVA
2025/02/20
2420
join查询可以⽆限叠加吗?MySQL对join查询有什么限制吗?
假设有一个复杂的业务系统,涉及到用户表(users)、订单表(orders)、商品表(products)、物流表(logistics)和支付表(payments)。如果编写如下的 JOIN 查询:
威哥爱编程
2025/02/24
2800
MySQL关于子查询经典面试题
面试官:“在MySQL中,进行多表查询时,你认为子查询(Subquery)和Join哪个效率更高?请详细说明你的理由,并提供一些具体的代码案例来支持你的观点。”
小白的大数据之旅
2025/01/24
890
MySQL关于子查询经典面试题
LeetCode 数据库专题
写一段SQL查询来展示每位用户的 唯一标识码(unique ID );如果某位员工没有唯一标识码,使用 null 填充即可。你可以以 任意 顺序返回结果表。查询结果的格式如下例所示:
wywwzjj
2023/05/09
1.5K0
LeetCode 数据库专题
SQL优化策略与实践:组合索引与最左前缀原则详解
SQL优化的方式有很多,它们可以帮助提高数据库查询的效率,减少资源的消耗。以下是一些常见的SQL优化方式:
阿珍
2025/04/21
1620
SQL优化策略与实践:组合索引与最左前缀原则详解
MySQL 分表查询
分表是一种数据库分割技术,用于将大表拆分成多个小表,以提高数据库的性能和可管理性。在MySQL中,可以使用多种方法进行分表,例如基于范围、哈希或列表等。下面将详细介绍MySQL如何分表以及分表后如何进行数据查询。
孟斯特
2023/10/19
1.9K0
MySQL 分表查询
【数据库设计和SQL基础语法】--连接与联接--多表查询与子查询基础(二)
子查询是指在一个查询语句内部嵌套另一个查询语句的过程。子查询可以嵌套在 SELECT、FROM、WHERE 或 HAVING 子句中,用于从数据库中检索数据或执行其他操作。子查询通常返回一个结果集,该结果集可以被包含它的主查询使用。 以下是子查询的一般概述:
喵叔
2023/12/21
5500
猫头虎分享:PostgreSQL 中分区表 PARTITION BY RANGE 的使用详解与数据迁移,索引创建细节详解
数据库作为现代技术的核心,如何高效地管理海量数据一直是技术团队关注的焦点。在 PostgreSQL 中,分区表(Partitioned Tables)为我们提供了极大的灵活性,尤其是通过 PARTITION BY RANGE 可以轻松实现按日期分区,大幅度提升查询性能和数据管理效率。今天,我们猫头虎技术团队将为大家详细剖析如何使用 PostgreSQL 的分区表及其背后的数据迁移与索引创建细节。
猫头虎
2024/09/17
3910
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 EXPLAIN 语句是一个强大的工具,用于分析和优化 SQL 查询。通过 EXPLAIN,你可以了解 MySQL 查询优化器是如何执行你的查询的,以及是否有可以改进的地方。本文将详细讲解 EXPLAIN 输出的各项指标,并说明如何利用这些指标来优化索引结构和 SQL 语句。
每周聚焦
2024/12/17
2660
深入解析MySQL的EXPLAIN:指标详解与索引优化
【详解】Hive怎样写exist/in子句
在大数据处理领域,Hive 是一个广泛使用的数据仓库工具,它允许用户通过类似于 SQL 的查询语言来操作存储在 Hadoop 分布式文件系统中的数据。本文将探讨如何在 Hive 中使用 ​​EXISTS​​ 和 ​​IN​​ 子句进行数据查询,这两种方法是 SQL 中常见的用于检查子查询结果是否存在的条件表达式。
大盘鸡拌面
2025/01/17
1700
【Java 进阶篇】MySQL多表查询之外连接详解
在MySQL数据库中,多表查询是一种常见且强大的功能,允许您在多个表之间执行联接操作,从而检索、过滤和组合数据。在本篇博客中,我们将深入探讨多表查询的一种类型,即外连接(Outer Join),并详细介绍其语法、用途和示例。无论您是刚开始学习数据库还是想深入了解MySQL的查询功能,本文都将为您提供有价值的信息。
繁依Fanyi
2023/10/12
8170
【Java 进阶篇】MySQL多表查询之外连接详解
数据表索引应用之覆盖索引
覆盖索引是数据库索引的一种类型,它存储了执行查询所需的所有数据。因此,在索引覆盖的查询方式下,查询过程可以完全依赖索引,无需对数据表进行额外查询。
参谋带个长
2024/07/18
1730
MySQL不使用子查询的原因
这些案例展示了如何通过不同优化策略提升MySQL查询性能,特别是在处理子查询时。以下是一些额外的优化建议:
用户11397231
2025/01/24
2490
MySQL不使用子查询的原因
MySQL - 索引详解
索引依托于存储引擎的实现,因此,每种存储引擎的索引都不一定完全相同,并且每种存储引擎也不一定支持所有索引类型。所有存储引擎支持每个表至少16个索引,总索引长度至少为256字节。大多数存储引擎有更高的额限制。
battcn
2018/08/03
9780
MySQL - 索引详解
相关推荐
SQL索引失效原因分析与解决方案
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验