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

简介: 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 UPDATE、DELETE 的 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;

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
存储 SQL 关系型数据库
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
mysql底层原理:索引、慢查询、 sql优化、事务、隔离级别、MVCC、redolog、undolog(图解+秒懂+史上最全)
|
存储 关系型数据库 MySQL
MySQL数据库索引的数据结构?
MySQL中默认使用B+tree索引,它是一种多路平衡搜索树,具有树高较低、检索速度快的特点。所有数据存储在叶子节点,非叶子节点仅作索引,且叶子节点形成双向链表,便于区间查询。
359 4
|
存储 关系型数据库 MySQL
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
|
存储 SQL 关系型数据库
MySQL 核心知识与索引优化全解析
本文系统梳理了 MySQL 的核心知识与索引优化策略。在基础概念部分,阐述了 char 与 varchar 在存储方式和性能上的差异,以及事务的 ACID 特性、并发事务问题及对应的隔离级别(MySQL 默认 REPEATABLE READ)。 索引基础部分,详解了 InnoDB 默认的 B+tree 索引结构(多路平衡树、叶子节点存数据、双向链表支持区间查询),区分了聚簇索引(数据与索引共存,唯一)和二级索引(数据与索引分离,多个),解释了回表查询的概念及优化方法,并分析了 B+tree 作为索引结构的优势(树高低、效率稳、支持区间查询)。 索引优化部分,列出了索引创建的六大原则
400 2
|
存储 关系型数据库 MySQL
MySQL覆盖索引解释
总之,覆盖索引就像是图书馆中那些使得搜索变得极为迅速和简单的工具,一旦正确使用,就会让你的数据库查询飞快而轻便。让数据检索就像是读者在图书目录中以最快速度找到所需信息一样简便。这样的效率和速度,让覆盖索引成为数据库优化师傅们手中的尚方宝剑,既能够提升性能,又能够保持系统的整洁高效。
467 9
|
机器学习/深度学习 关系型数据库 MySQL
对比MySQL全文索引与常规索引的互异性
现在,你或许明白了这两种索引的差异,但任何技术决策都不应仅仅基于理论之上。你可以创建你的数据库实验环境,尝试不同类型的索引,看看它们如何影响性能,感受它们真实的力量。只有这样,你才能熟悉它们,掌握什么时候使用全文索引,什么时候使用常规索引,以适应复杂多变的业务需求。
424 12
|
SQL 存储 关系型数据库
MySQL选错索引了怎么办?
本文探讨了MySQL中因索引选择不当导致查询性能下降的问题。通过创建包含10万行数据的表并插入数据,分析了一条简单SQL语句在不同场景下的执行情况。实验表明,当数据频繁更新时,MySQL可能因统计信息不准确而选错索引,导致全表扫描。文章深入解析了优化器判断扫描行数的机制,指出基数统计误差是主要原因,并提供了通过`analyze table`重新统计索引信息的解决方法。
474 3
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
716 158
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1895 152

推荐镜像

更多