数据库查询——索引优化查询方法

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 数据库查询——索引优化查询方法

数据库查询——索引优化查询方法

本文讲解在数据库查询的时候,一个优化查询的方法,这个方法就是索引优化,讲解其中的原理和实现方法。

简介

首先这是一个简单的数据库,这个数据库很正常,如果采取mybatis-plus进行查询,也就是跟这篇文章中的代码一样:Java图书目录管理系统CRUD展示(springboot+vue+mybatis-plus)

/*
 Navicat MySQL Data Transfer
 Source Server         : localhost_3306
 Source Server Type    : MySQL
 Source Server Version : 80028
 Source Host           : localhost:3306
 Source Schema         : projectdatabase
 Target Server Type    : MySQL
 Target Server Version : 80028
 File Encoding         : 65001
 Date: 31/01/2023 22:24:02
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for book
-- ----------------------------
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book`  (
  `isbn` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `author` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `publisher` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `pubdate` datetime NOT NULL,
  `price` decimal(10, 2) NOT NULL,
  `id` int NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`, `isbn`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- Records of book
-- ----------------------------
INSERT INTO `book` VALUES ('9780439227148', 'The Call of the Wild', 'Jack London', 'Scholastic Press', '2001-01-01 00:00:00', 39.40, 1);
INSERT INTO `book` VALUES ('9787501592401', 'The Old Man and the Sea', 'Ernest Hemingway', 'Knowledge Press', '2023-01-30 00:00:00', 25.80, 2);
INSERT INTO `book` VALUES ('9787501592401', 'The Old Man and the Sea', 'Ernest Hemingway', 'Knowledge Press', '2023-01-31 13:02:42', 25.80, 3);
INSERT INTO `book` VALUES ('9780439227148', 'The Call of the Wild', 'Jack London', 'Scholastic Press', '2023-01-30 16:00:00', 34.90, 6);
INSERT INTO `book` VALUES ('9781772262902', 'Oliver Twist', 'Charles Dickens', 'Engage Books', '2023-01-03 16:00:00', 45.00, 7);
SET FOREIGN_KEY_CHECKS = 1;

索引优化原理

索引优化:使用合适的索引可以加快查询速度。例如,在book表中,isbn、title、author和publisher列都是常用作搜索的字段,应为这些字段建立相应的索引。

索引可以大大提高数据库查询效率,例如在book表中的isbn、title、author和publisher列上建立相应的索引,可以极大地优化图书管理系统的CRUD操作。

以下是为book表中的isbn、title、author和publisher列分别建立索引的SQL语句:

ALTER TABLE `book` ADD INDEX `idx_isbn`(`isbn`);
ALTER TABLE `book` ADD INDEX `idx_title`(`title`);
ALTER TABLE `book` ADD INDEX `idx_author`(`author`);
ALTER TABLE `book` ADD INDEX `idx_publisher`(`publisher`);

执行以上SQL语句即可在book表中为指定列建立索引。在查询时,MySQL会首先使用索引来检索符合条件的记录,并返回结果,从而避免全表扫描,提高查询速度。

需要注意的一点是,在建立索引的同时也会增加数据的维护成本和存储空间。因此,在选择索引字段和类型时应该视情况而定,避免过度使用,以免影响系统性能和空间占用。此外,对于频繁更新的表,过多使用索引也会降低更新速度,并且还会产生锁等额外的开销,需要结合实际需求进行选型配置。

添加索引之后,对于这个book类就是这个样子了

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("book")
public class Book {
    @TableId(type = IdType.AUTO)
    private Long id;
    @TableIndex(name = "idx_isbn", type = IndexType.BTREE)
    private String isbn;
    @TableIndex(name = "idx_title", type = IndexType.BTREE)
    private String title;
    @TableIndex(name = "idx_author", type = IndexType.BTREE)
    private String author;
    @TableIndex(name = "idx_publisher", type = IndexType.BTREE)
    private String publisher;
    private Date pubdate;
    private Double price;
}

最后来一个总结:

简单地说,索引就是数据库中用于提高查询效率的一种数据结构。它可以类比于字典的目录,可以帮助我们更快地定位到需要查询的记录。在数据库中,索引一般用B-tree(平衡树)或哈希表实现。其中,B-tree是一种多阶段平衡树,通常用于处理基于磁盘存储的数据检索;哈希表则主要针对内存型数据库,它可以使读取操作达到O(1)的时间复杂度。

在Mybatis-Plus中,通过@TableIndex注解可以为实体类中的列建立相应的索引,如上述Book实体类中的四个字段isbn、title、author和publisher,分别添加了名为idx_isbn、idx_title、idx_author和idx_publisher的BTREE类型索引。

当进行查询操作时,如果查询语句中带有这些具有索引的字段,则MySQL会选择使用相关的索引来定位符合条件的记录。由于索引能够极大地加快查询操作,因此在实际开发中,我们往往需要为需要经常进行查询的字段添加相应的索引,从而提高系统的响应速度。

需要注意的是,在建立索引的过程中,需要根据实际业务需求选择建立哪些字段的索引,同时需要权衡索引会带来的维护和存储开销。过多或不必要的索引反而会拖慢系统查询和写入速度,因此需要谨慎地进行优化。同时,在数据库数据量较大时,也可以采取分区等方式进行优化以提高性能和可用性。

总之,索引是一种重要的数据库优化手段,可以帮助我们更快地查找和定位需要的数据,但也需要根据实际情况进行优化和管理。

实际案例

假设我们有一个业务需求:需要根据作者名查询图书信息。在默认情况下,我们可以通过以下SQL语句进行查询:

SELECT * FROM book WHERE author = '张三';

但如果book表中数据量非常大,则这样的查询操作可能会耗费很长时间。为了优化查询效率,我们可以针对author字段建立索引,使其能够更快地查询到匹配的记录。

在Mybatis-Plus中,我们可以在Book实体类中对author属性添加@TableIndex注解,代码如下:

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("book")
public class Book {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String isbn;
    private String title;
    @TableIndex(name = "idx_author", type = IndexType.BTREE)
    private String author;
    private String publisher;
    private Date pubdate;
    private Double price;
}

然后,在数据库中执行以下SQL语句,为author字段建立相应的BTREE类型的索引:

CREATE INDEX idx_author ON book(author);

这样,当我们通过以下SQL语句查询图书信息时,MySQL数据库就可以使用idx_author索引来提高查询效率:

SELECT * FROM book WHERE author = '张三';

由于索引可以帮助我们更快定位到符合条件的记录,因此当book表中数据量较大时,使用索引会大幅提高查询效率,同时也减轻了数据库的压力。

当然,在实际开发中,我们还需要根据具体业务需求进行优化。例如,如果对多个字段需要进行联合查询,则可以为这些字段创建复合索引等等。

  • 原理分析

加入索引对查询效率的提升主要来自于索引的数据结构和位置,它可以有效地减少数据库中需要扫描的数据量。

在MySQL中,每一个索引都是一棵B-tree或者Hash表。当我们为author字段建立了索引之后,MySQL会把Autor字段的值按照索引的数据结构进行存储,在读取时只需要查找到符合条件的记录即可,而不必遍历整张表。

假设book表有1000万条记录,如果没有为author字段建立索引,则MySQL需要遍历整张表来寻找符合条件的记录,这个操作是非常耗时的。而当我们为author字段建立索引时,MySQL只需要在这棵B-tree上进行检索即可,由于它使用的是平衡树的数据结构,所以它每次最多需要比较log(N)次,其中N是这个B-tree的叶子节点数量。因此使用索引查询的速度是非常快的,甚至可以达到近似O(1)的时间复杂度。

需要注意的是,在实际应用中为表的字段添加索引并不是越多越好,过多的索引也可能会拖慢数据库的写入操作,并消耗大量的磁盘空间。因此,我们需要在对具体的业务需求进行分析和优化之后决定是否需要添加索引,以及需要为哪些字段添加索引。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
数据采集 数据库 Python
有哪些方法可以验证用户输入数据的格式是否符合数据库的要求?
有哪些方法可以验证用户输入数据的格式是否符合数据库的要求?
144 75
|
6天前
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
28 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
30天前
|
缓存 NoSQL JavaScript
Vue.js应用结合Redis数据库:实践与优化
将Vue.js应用与Redis结合,可以实现高效的数据管理和快速响应的用户体验。通过合理的实践步骤和优化策略,可以充分发挥两者的优势,提高应用的性能和可靠性。希望本文能为您在实际开发中提供有价值的参考。
55 11
|
29天前
|
SQL Java 数据库连接
【潜意识Java】MyBatis中的动态SQL灵活、高效的数据库查询以及深度总结
本文详细介绍了MyBatis中的动态SQL功能,涵盖其背景、应用场景及实现方式。
98 6
|
2月前
|
SQL Oracle 数据库
使用访问指导(SQL Access Advisor)优化数据库业务负载
本文介绍了Oracle的SQL访问指导(SQL Access Advisor)的应用场景及其使用方法。访问指导通过分析给定的工作负载,提供索引、物化视图和分区等方面的优化建议,帮助DBA提升数据库性能。具体步骤包括创建访问指导任务、创建工作负载、连接工作负载至访问指导、设置任务参数、运行访问指导、查看和应用优化建议。访问指导不仅针对单条SQL语句,还能综合考虑多条SQL语句的优化效果,为DBA提供全面的决策支持。
95 11
|
29天前
|
缓存 关系型数据库 MySQL
【深入了解MySQL】优化查询性能与数据库设计的深度总结
本文详细介绍了MySQL查询优化和数据库设计技巧,涵盖基础优化、高级技巧及性能监控。
248 0
|
2月前
|
SQL JavaScript 程序员
数据库LIKE查询屡试不爽?揭秘大多数人都忽视的秘密操作符!
本文分析了因数据库中的不可见空白字符导致的数据查询问题,探讨了问题的成因与特性,并提出了使用 SQL 语句修复问题的有效方案。同时,总结了避免类似问题的经验和注意事项。
46 0
|
25天前
|
关系型数据库 MySQL 数据库连接
数据库连接工具连接mysql提示:“Host ‘172.23.0.1‘ is not allowed to connect to this MySQL server“
docker-compose部署mysql8服务后,连接时提示不允许连接问题解决
|
12天前
|
关系型数据库 MySQL 数据库
Docker Compose V2 安装常用数据库MySQL+Mongo
以上内容涵盖了使用 Docker Compose 安装和管理 MySQL 和 MongoDB 的详细步骤,希望对您有所帮助。
88 42
|
3天前
|
关系型数据库 MySQL 网络安全
如何排查和解决PHP连接数据库MYSQL失败写锁的问题
通过本文的介绍,您可以系统地了解如何排查和解决PHP连接MySQL数据库失败及写锁问题。通过检查配置、确保服务启动、调整防火墙设置和用户权限,以及识别和解决长时间运行的事务和死锁问题,可以有效地保障应用的稳定运行。
41 25

热门文章

最新文章