MySQL高级篇——索引的创建与设计原则(上)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL高级篇——索引的创建与设计原则 (上)

文章目录:


1.索引的分类

2.创建索引的三种方式

2.1 方式一:CREATE TABLE

2.1.1 小例子

2.1.2 普通索引

2.1.3 唯一性索引

2.1.4 主键索引

2.1.5 单列索引

2.1.6 联合索引

2.1.7 全文索引

2.2 方式二:ALTER TABLE ... ADD INDEX ...

2.3 方式三:CREATE INDEX ... ON ...

3.删除索引的两种方式

3.1 使用ALTER TABLE删除索引

3.2 使用DROP INDEX语句删除索引

4.索引的设计原则(未完待续,明天补全......

4.1 哪些情况适合创建索引?

4.1.1 字段的数值有唯一性的限制

4.1.2 频繁作为 WHERE 查询条件的字段

4.1.3 经常 GROUP BY ORDER BY 的列

4.1.4 UPDATEDELETE WHERE 条件列

4.1.5 DISTINCT 字段需要创建索引

4.1.6 多表 JOIN 连接操作时,创建索引注意事项

4.1.7 使用列的类型小的创建索引

4.1.8 使用字符串前缀创建索引

4.1.9 区分度高(散列性高)的列适合作为索引

4.1.10 使用最频繁的列放到联合索引的左侧

4.1.11 在多个字段都要创建索引的情况下,联合索引优于单值索引

4.2 限制索引的数目

4.3 哪些情况不适合创建索引?

4.3.1 where中使用不到的字段,不要设置索引

4.3.2 数据量小的表最好不要使用索引

4.3.3 有大量重复数据的列上不要建立索引

4.3.4 避免对经常更新的表创建过多的索引

4.3.5 不建议用无序的值作为索引

4.3.6 删除不再使用或者很少使用的索引

4.3.7 不要定义冗余或重复的索引

1.索引的分类


MySQL的索引包括普通索引、唯一性索引、全文索引、单列索引、多列索引和空间索引等。

功能逻辑上说,索引主要有 4 种,分别是普通索引、唯一索引、主键索引、全文索引。

按照物理实现方式,索引可以分为 2 种:聚簇索引和非聚簇索引。

按照作用字段个数进行划分,分成单列索引和联合索引。


2.创建索引的三种方式


2.1 方式一:CREATE TABLE


2.1.1 小例子

CREATE DATABASE dbtest2;
USE dbtest2;
CREATE TABLE dept (
    dept_id INT PRIMARY KEY AUTO_INCREMENT,
    dept_name VARCHAR(20)
);
SHOW INDEX FROM dept;


CREATE TABLE emp (
    emp_id INT PRIMARY KEY AUTO_INCREMENT,
    emp_name VARCHAR(20) UNIQUE,
    dept_id INT,
    CONSTRAINT fk_emp_dept_id FOREIGN KEY(dept_id) REFERENCES dept(dept_id)
);
SHOW INDEX FROM emp;


2.1.2 普通索引

CREATE TABLE book (
  book_id INT,
  book_name VARCHAR(100),
  `authors` VARCHAR(100),
  info VARCHAR(100),
  `comment` VARCHAR(100),
  year_publication YEAR,
  INDEX idx_bname(book_name)
);
SHOW INDEX FROM book;


如果我们写一个简单的sql语句,在where后面用 book_name 来筛选,可以通过 explain 性能分析工具来看看是什么样的?

EXPLAIN 
SELECT *
FROM book
WHERE book_name = 'mysql';


2.1.3 唯一性索引

CREATE TABLE book1 (
    book_id INT,
    book_name VARCHAR(100),
    `authors` VARCHAR(100),
    info VARCHAR(100),
    `comment` VARCHAR(100),
    year_publication YEAR,
    UNIQUE INDEX uk_idx_cmt(`comment`)
);
SHOW INDEX FROM book1;


接下来,依次向表中插入三条记录,在插入第二条记录的时候,就会报错。而第三条记录是正常执行的。

INSERT INTO book1(book_id, book_name, `comment`)
VALUES(1, 'MySQL高级', '适合有数据库开发经验的人员学习');
INSERT INTO book1(book_id, book_name, `comment`)
VALUES(1, 'MySQL高级', '适合有数据库开发经验的人员学习');
INSERT INTO book1(book_id, book_name, `comment`)
VALUES(1, 'MySQL高级', NULL);


最终,在book1这张表中,将存在两条记录。


2.1.4 主键索引

CREATE TABLE book2 (
    book_id INT PRIMARY KEY,
    book_name VARCHAR(100),
    `authors` VARCHAR(100),
    info VARCHAR(100),
    `comment` VARCHAR(100),
    year_publication YEAR
);
SHOW INDEX FROM book2;


2.1.5 单列索引

其实我们上面创建的那些都是单列索引。

CREATE TABLE book3 (
    book_id INT ,
    book_name VARCHAR(100),
    AUTHORS VARCHAR(100),
    info VARCHAR(100) ,
    COMMENT VARCHAR(100),
    year_publication YEAR,
    UNIQUE INDEX idx_bname(book_name)
);
SHOW INDEX FROM book3;


2.1.6 联合索引

CREATE TABLE book4 (
    book_id INT ,
    book_name VARCHAR(100),
    AUTHORS VARCHAR(100),
    info VARCHAR(100) ,
    COMMENT VARCHAR(100),
    year_publication YEAR,
    INDEX mul_bid_bname_info(book_id, book_name, info)
);
SHOW INDEX FROM book4;


下面我们通过两条sql来分析一下,联合索引在查找过程中是怎么走的?

EXPLAIN 
SELECT *
FROM book4
WHERE book_id = 1001 AND book_name = 'mysql';

解释:因为我们建的联合索引是 book_id, book_name, info 这样的顺序,所以在构建B+树的时候,就是先按照 book_id 来进行排序,当book_id相同时,再按照 book_name来排序,当book_name一样时,最后按照info来排序。(在B+树中,book_name实际上是位于book_id下方的,查找一定是先经过book_id、后经过book_name的)

所以上面这条sql,会先走book_id,再走book_name的。


EXPLAIN 
SELECT *
FROM book4
WHERE book_name = 'mysql';

经过上面的分析,那么这条sql为什么就没有走联合索引呢?(这book_name不是存在于联合索引中吗?),这里其实还是构建B+树的顺序问题,你要想在where筛选中走book_name索引,你就必须先要走book_id索引的,因为book_name在联合索引中位于book_id之后,所以在B+树中book_name就处于book_id下方,你连B+树的第二层(假设)都还没走到,又何谈到达B+树的第三层呢?    所以这条sql是不会走索引的。


2.1.7 全文索引

CREATE TABLE test4 (
    id INT NOT NULL,
    NAME CHAR(30) NOT NULL,
    age INT NOT NULL,
    info VARCHAR(255),
    FULLTEXT INDEX futxt_idx_info(info(50))
);
SHOW INDEX FROM test4;


2.2 方式二:ALTER TABLE ... ADD INDEX ...

DROP TABLE IF EXISTS book5;
CREATE TABLE book5 (
    book_id INT ,
    book_name VARCHAR(100),
    `authors` VARCHAR(100),
    info VARCHAR(100) ,
    `comment` VARCHAR(100),
    year_publication YEAR
);
ALTER TABLE book5 ADD INDEX idx_cmt(`comment`);
ALTER TABLE book5 ADD UNIQUE INDEX uk_idx_bname(book_name);
ALTER TABLE book5 ADD INDEX mul_bid_bname_info(book_id, book_name, info);
SHOW INDEX FROM book5;


2.3 方式三:CREATE INDEX ... ON ...

DROP TABLE IF EXISTS book6;
CREATE TABLE book6 (
    book_id INT ,
    book_name VARCHAR(100),
    `authors` VARCHAR(100),
    info VARCHAR(100) ,
    `comment` VARCHAR(100),
    year_publication YEAR
);
CREATE INDEX idx_cmt ON book6(`comment`);
CREATE UNIQUE INDEX uk_idx_bname ON book6(book_name);
CREATE INDEX mul_bid_bname_info ON book6(book_id, book_name, info);
SHOW INDEX FROM book6;

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
24天前
|
存储 关系型数据库 MySQL
阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?
尼恩是一位资深架构师,他在自己的读者交流群中分享了关于MySQL索引的重要知识点。索引是帮助MySQL高效获取数据的数据结构,主要作用包括显著提升查询速度、降低磁盘I/O次数、优化排序与分组操作以及提升复杂查询的性能。MySQL支持多种索引类型,如主键索引、唯一索引、普通索引、全文索引和空间数据索引。索引的底层数据结构主要是B+树,它能够有效支持范围查询和顺序遍历,同时保持高效的插入、删除和查找性能。尼恩还强调了索引的优缺点,并提供了多个面试题及其解答,帮助读者在面试中脱颖而出。相关资料可在公众号【技术自由圈】获取。
|
1月前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
61 3
Mysql(4)—数据库索引
|
15天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
77 1
|
26天前
|
存储 关系型数据库 MySQL
如何在MySQL中进行索引的创建和管理?
【10月更文挑战第16天】如何在MySQL中进行索引的创建和管理?
54 1
|
16天前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
47 0
|
27天前
|
监控 关系型数据库 MySQL
mysql8索引优化
综上所述,深入理解和有效实施这些索引优化策略,是解锁MySQL 8.0数据库高性能查询的关键。
28 0
|
1月前
|
SQL 关系型数据库 MySQL
美团面试:mysql 索引失效?怎么解决? (重点知识,建议收藏,读10遍+)
本文详细解析了MySQL索引失效的多种场景及解决方法,包括破坏最左匹配原则、索引覆盖原则、前缀匹配原则、`ORDER BY`排序不当、`OR`关键字使用不当、索引列上有计算或函数、使用`NOT IN`和`NOT EXISTS`不当、列的比对等。通过实例演示和`EXPLAIN`命令分析,帮助读者深入理解索引失效的原因,并提供相应的优化建议。文章还推荐了《尼恩Java面试宝典》等资源,助力面试者提升技术水平,顺利通过面试。
|
8天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
22 4
|
6天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
19 1
|
17天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
59 2