数据库索引

在大多数据库系统中,数据库读取(查询)数据的次数远大于写入数据的次数,因此,如何优化数据读取的效率是数据库系统的主要工作之一。

数据库索引是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中的数据。

索引是一种以空间代价换取时间效率提升的方法。

  • 聚集索引(Clustered Index)/聚簇索引
  • 非聚集索引(Non-Clustered Index)/辅助索引/二级索引

(一)聚集索引

聚集索引也称聚簇索引:将数据存储与索引放到一起,索引结构的叶子节点保存所有数据。在聚集索引中,表中行的逻辑顺序与主键值的索引顺序相同,因此,一个表只有一个聚集索引

1. 创建索引

创建方式一:在建表时定义主键

创建方式二:修改表时创建,如表是从外部导入的则没有主键。

ALTER TABLE stu ADD PRIMARY KEY(sno);

问题:如果不定义主键能否创建聚集索引?

如果不定义主键,系统将使用第一个唯一(UNIQUE)索引创建聚集索引。 如果表没有主键,且没有唯一索引,则系统会自动生成一个rowid作为隐藏的聚集索引主键。

(二)非聚集索引

非聚集索引也称二级索引或辅助索引,除聚集索引外其他索引都称为二级索引。

二级索引是在非主键字段上创建的索引;

  1. 创建索引

(1)CREATE TABLE tudent(

...... INDEX idx_sname(sname)

)CHARSET=gbk;

(2)CREATE INDEX idx_sname ON student(sname);

a.联合索引也称多列索引,是建立在多个字段上的索引;

CREATE INDEX idx_sname_birthday ON student(sname,birthday);

b.全文索引:能够将存储于数据库中的文本中的任意内容查找出来的技术。

CREATE FULLTEXT INDEX ft_remarks ON student(remarks);

c. 前缀索引

CREATE INDEX pf_cname ON course ( cname(4) );

算法:

SELECT COUNT(DISTINCT LEFT(cname,3))/COUNT(cname) FROM course

length值取3时,执行结果为0.7778,

SELECT COUNT(DISTINCT LEFT(cname,4))/COUNT(cname) FROM course

length值取4时,执行结果为1.0000。


总结:

1.建表时创建索引

CREATE TABLE 表名(字段列表,UNIQUE \| FULLTEXT \| SPATIAL INDEX | KEY <index_name> (<column_name>(length) ASC \| DESC ,...... ));

例:

(1)在sname字段和dept字段上创建联合索引idx_sname_dept;

(2)在remarks字段上创建全文索引ft_remarks。

CREATE TABLE student(

...... INDEX idx_sname_dept(sname,dept),

FULLTEXT ft_remarks(remarks)) ;

2.建表后创建索引

CREATE UNIQUE \| FULLTEXT \| SPATIAL INDEX <index_name> ON <table_name> (<column_name>(length) ASC \| DESC ...... ) ;

【例】在course表的cname字段上创建唯一索引uk_cname

CREATE UNIQUE INDEX uk_cname ON course (cname);

【例】在course表的cname字段上创建前缀索引pf_cname

CREATE INDEX pf_cname ON course ( cname(4) );

3.修改表结构添加索引

ALTER TABLE <table_name> ADD UNIQUE \| FULLTEXT \| SPATIAL INDEX <index_name> (<column_name>(length) ASC \| DESC......) ;

【例】在score表的sno字段和cno字段创建组合唯一索引,约束同一个学生的同一门课成绩只能出现一次。

ALTER TABLE score ADD UNIQUE INDEX idx_sno_cno( sno, cno );

查看索引:

SHOW INDEX FROM <table_name> where \;

【例】查看course表中的索引。

SHOW INDEX FROM course;

【例】查看student表中的索引使用。

EXPLAIN SELECT * FROM student WHERE sname LIKE '王%';

删除索引

可以通过ALTER TABLE语句和DROP INDEX语句两种方式删除索引。

ALTER TABLE <table_name> DROP INDEX <index_name>;

DROP INDEX <index_name> ON <table_name> ;

【例】删除student表中的idx_sname_dept索引。

ALTER TABLE student1 DROP INDEX idx_sname_dept;

【例】删除score表中的uk_sno_cno索引。

DROP INDEX uk_sno_cno ON score;

(三)索引类别

(1)PRIMARY:主键索引,索引列值唯一且不能为空;

(2)INDEX:普通索引,索引列没有任何限制。

(3)UNIQUE:唯一索引,索引列的值必须是唯一的,但允许有空值。

(4)FULLTEXT:全文索引。

(5)SPATIAL:空间索引,对空间数据类型的字段建立的索引(自学)。

(6)哈希索引(也称HASH索引):对于每一条行数据,存储引擎对所有的索引列计算一个哈希码。将所有的哈希码存储在索引中,同时在哈希表中保存指向每一个数据行的指针。系统自建。

(四)索引的设计原则

(1)索引命名符合规范;

主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引名为 idx_字段名。

(2)条件子句中频繁使用的字段、数字型的字段、存储空间较小的字段适合建立索引;

选择在WHERE子句、GROUP BY子句、ORDER BY子句或表与表之间连接运算等频繁使用的字段上建立索引

(3)重复值较高的字段、更新频繁的字段不适合建立索引;

(4)索引字段的值很长,最好使用字段值的前缀建立索引;

CREATE INDEX idx_came ON course(cname(6));

(5)限制索引的数量,否则会降低系统效率;

(五)索引总结

优点:使用索引,可以在查询的过程中,提高系统的性能。

缺点:占用更多的存储空间;索引的维护成本很高,每次新增、删除数据都需要整理B+树结构(结点分裂、合并)拖慢了增删改的速度。

索引必须根据表中的列数据的使用特性进行创建,而不能随意建立,在什么情况下使用索引、使用什么类型的索引以及在什么情况下不使用索引,需要根据数据库的设计需求或使用经验来判断。

相关推荐
凌虚21 小时前
面向 MySQL 用户的 PostgreSQL 快速上手指南
数据库·后端·架构
五阿哥永琪21 小时前
MySQL中操作json的函数!
数据库·mysql·json
来者皆善21 小时前
了解Mysql优化吗?如何优化索引?
数据库·mysql
赤壁小虾1 天前
【渲染流水线】[逐片元阶段]-[透明度测试]以UnityURP为例
java·前端·数据库
MC皮蛋侠客1 天前
SQLAlchemy 系列(七):高级建模与高效写入——批量 DML、方言与扩展
数据库·python
奈斯先生Vector1 天前
把 Midjourney 二次编辑做成生产系统:customId 能力令牌、Action Graph 与 WebUI 精修工作台
数据库·人工智能·架构·aigc·音视频·midjourney
Lethehong1 天前
双擎并驱·全链路并行:KFS让TB级异构增量同步秒级到达
数据库
MC皮蛋侠客1 天前
SQLAlchemy 系列(八):AsyncIO、并发与 Web 生命周期——让每个并发任务持有自己的 Session
数据库·python
一水1 天前
Redis实战:一个AI工作流系统里的五个应用场景,从传参到限流的完整链路
数据库·redis·wpf
Ai拆代码的曹操1 天前
MySQL GROUP BY 性能优化:执行计划分析 + 索引重构实战
mysql·性能优化·重构