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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
云数据库 RDS MySQL Serverless,价值2615元额度,1个月
简介: 数据库查询——索引优化查询方法

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

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

简介

首先这是一个简单的数据库,这个数据库很正常,如果采取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)的时间复杂度。

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

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1天前
|
API 数据库 Python
Python web框架fastapi数据库操作ORM(二)增删改查逻辑实现方法
Python web框架fastapi数据库操作ORM(二)增删改查逻辑实现方法
|
1天前
|
安全 数据管理 数据库
数据管理DMS产品使用合集之要将某个DMS实例中的特定数据库授权给某个用户进行查询,操作步骤是怎样的
阿里云数据管理DMS提供了全面的数据管理、数据库运维、数据安全、数据迁移与同步等功能,助力企业高效、安全地进行数据库管理和运维工作。以下是DMS产品使用合集的详细介绍。
|
1天前
|
关系型数据库 数据库 开发者
关系型数据库查询避免SELECT *
有时候你可能会遇到需要选择表中的所有列的情况,但这应该是例外而不是常态。在大多数情况下,你应该尽量避免使用 `SELECT *`。
6 1
|
2天前
|
SQL 分布式计算 关系型数据库
云原生数据仓库产品使用合集之可以把ADB MySQL湖仓版数据库做成页面查询的数据库吗
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
|
2天前
|
存储 缓存 关系型数据库
关系型数据库数据库表设计的优化
您可以优化关系型数据库的表设计,提高数据库的性能、可维护性和可扩展性。但请注意,每个数据库和应用程序都有其独特的需求和挑战,因此在实际应用中需要根据具体情况进行调整和优化。
10 4
|
3天前
|
数据库 UED 索引
构建高效的数据库索引:提升查询性能的关键技巧
本文将深入探讨数据库索引的设计和优化,介绍如何构建高效的数据库索引以提升查询性能。通过学习本文,读者将掌握数据库索引的原理、常见类型以及优化策略,从而在实际应用中提升数据库查询效率。
|
5天前
|
SQL 缓存 数据库
在Python Web开发过程中:数据库与缓存,如何使用ORM(例如Django ORM)执行查询并优化查询性能?
在Python Web开发中,使用ORM如Django ORM能简化数据库操作。为了优化查询性能,可以:选择合适索引,避免N+1查询(利用`select_related`和`prefetch_related`),批量读取数据(`iterator()`),使用缓存,分页查询,适时使用原生SQL,优化数据库配置,定期优化数据库并监控性能。这些策略能提升响应速度和用户体验。
8 0
|
11天前
|
关系型数据库 MySQL 分布式数据库
《MySQL 简易速速上手小册》第6章:MySQL 复制和分布式数据库(2024 最新版)
《MySQL 简易速速上手小册》第6章:MySQL 复制和分布式数据库(2024 最新版)
46 2
|
27天前
|
SQL 数据可视化 关系型数据库
轻松入门MySQL:深入探究MySQL的ER模型,数据库设计的利器与挑战(22)
轻松入门MySQL:深入探究MySQL的ER模型,数据库设计的利器与挑战(22)
108 0
|
8天前
|
SQL 存储 关系型数据库
数据库开发之mysql前言以及详细解析
数据库开发之mysql前言以及详细解析
17 0