| 从功能逻辑上说,索引主要有4种,分别是普通索引、唯一索引、主键索引、全文索引 |
| 按照物理实现方式,索引可以分为2种:聚簇索引和非聚簇索引 |
| 按照作用字段个数进行划分,分成单列索引和联合索引 |
| |
| 1.1 普通索引 |
| 在创建普通索引时,不附加任何限制条件,只是用于提高查询效率。这类索引可以创建在任何数据类型中,其值是否唯一和非空,要由字段本身的完整性约束条件决定。 |
| 建立索引以后,可以通过索引进行查询。例如,在表student的字段name上建立一个普通索引,查询记录时就可以根据该索引进行查询。 |
| |
| 1.2 唯一性索引 |
| 使用UNIQUE参数可以设置索引为唯一性索引,在创建唯一性索引时,限制该索引的值必须是唯一的,但允许空值。在一张数据表里可以有多个唯一索引。 |
| |
| 1.3 主键索引 |
| 主键索引就是一种特殊的唯一性索引,在唯一索引的基础上增加了不为空的约束,也就是NOT NULL+UNIQUE,一张表里最多只有一个主键索引。 |
| |
| 1.4 单列索引 |
| 在表中的单个字段上创建索引。单列索引只根据该字段进行索引。单列索引可以是普通索引,也可以是唯一性索引,还可以是全文索引。只要保证该索引只对应一个字段即可。 |
| 一个表可以有多个单列索引。 |
| |
| 1.5 多列索引 |
| 多列索引是在表的多个字段组合上创建一个索引。该索引指向创建时对应的多个字段,可以通过这几个字段进行查询,但是只有查询条件中使用了这些字段中的第一个字段时才会被使用。 |
| 例如,在表中的字段id、name和gender上建立一个多列索引idx_id_name_gender,只有在查询条件中使用了字段id时该索引才会被使用。使用组合索引时遵循最左前缀集合。 |
| |
| 1.6 全文索引 |
| 全文索引(也称全文检索)是目前搜索引擎使用的一种关键技术。它能够利用【分词技术】等多种算法智能分析出文本文字中关键词的频率和重要性,然后按照一定的算法规则智能地筛选出 |
| 我们想要的搜索结果。全文索引非常适合大型数据集,对于小的数据集,它的用处比较小。 |
| |
| 1.7 空间索引 |
| 使用参数SPATIAL可以设置索引为空间索引。空间索引只能建立在空间数据类型上,这样可以提高系统获取空间数据的效率。MySQL中的空间数据类型包括GEOMETRY、POINT、LINESTRING |
| 和POLYGON等。目前只有MyISAM存储引擎支持空间检索,而且索引的字段不能为空值。对于初学者来说,这类索引很少会用到。 |
- 隐式的方式创建索引。在声明有主键约束、唯一性约束、外键约束的字段上,会自动的添加相关的索引
| CREATE DATABASE dbtest2; |
| |
| USE dbtest2; |
| |
| CREATE TABLE dept( |
| dept_id INT PRIMARY KEY AUTO_INCREMENT, |
| dept_name VARCHAR(20) |
| ); |
| |
| CREATE TABLE emp( |
| emp_id INT PRIMARY KEY AUTO_INCREMENT, |
| emp_name VARCHAR(20) UNIQUE, |
| dept_id INT, |
| CONSTRAINT emp_dept_id_fk FOREIGN KEY(dept_id) REFERENCES dept(dept_id) |
| ); |
| CREATE TABLE table_name [col_name data_type] |
| [UNIQUE | FULLTEXT | SPATIAL] [INDEX | KEY] [index_name] (col_name [length]) [ASC | |
| DESC] |
| |
| UNIQUE 、 FULLTEXT 和 SPATIAL 为可选参数,分别表示唯一索引、全文索引和空间索引; |
| INDEX 与 KEY 为同义词,两者的作用相同,用来指定创建索引; |
| index_name 指定索引的名称,为可选参数,如果不指定,那么MySQL默认col_name为索引名; |
| col_name 为需要创建索引的字段列,该列必须从数据表中定义的多个列中选择; |
| length 为可选参数,表示索引的长度,只有字符串类型的字段才能指定索引长度; |
| ASC 或 DESC 指定升序或者降序的索引值存储 |
| 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) # 声明索引 |
| ); |
| |
| # 通过命令查看索引 |
| # 方式1: |
| SHOW CREATE TABLE book; |
| |
| # 方式2: |
| SHOW INDEX FROM book; |
| |
| # 性能分析工具:EXPLAIN |
| EXPLAIN SELECT * FROM book WHERE book_name = 'mysql高级'; |
| # 声明有唯一索引的字段,在添加数据时,要保证唯一性,但是可以添加null |
| 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; |
| |
| # 插入1条数据 |
| INSERT INTO book1(book_id,book_name,COMMENT) |
| VALUES(1,'Mysql高级','适合有数据库开发经验的人员学习'); |
| |
| INSERT INTO book1(book_id,book_name,COMMENT) |
| VALUES(2,'Mysql高级',NULL); |
| # 通过定义主键约束的方式定义主键索引 |
| 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; |
| |
| # 通过删除主键约束的方式删除主键索引 |
| ALTER TABLE book2 DROP PRIMARY KEY; |
| 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; |
| 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; |
| |
| # 分析 |
| EXPLAIN SELECT * FROM book4 WHERE book_id = 1001 AND book_name = 'mysql'; |
| |
| EXPLAIN SELECT * FROM book4 WHERE book_name = 'mysql'; |
| # 案例1 |
| 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 |
| CREATE TABLE articles ( |
| id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, |
| title VARCHAR (200), |
| body TEXT, |
| FULLTEXT index (title, body) |
| ) ENGINE = INNODB ; |
| |
| # 在MySQL5.7及之后版本中可以不指定最后的ENGINE了,因为在此版本中InnoDB支持全文索引 |
| |
| # 案例3 |
| CREATE TABLE `papers` ( |
| `id` int(10) unsigned NOT NULL AUTO_INCREMENT, |
| `title` varchar(200) DEFAULT NULL, |
| `content` text, |
| PRIMARY KEY (`id`), |
| FULLTEXT KEY `title` (`title`,`content`) |
| ) ENGINE=MyISAM DEFAULT CHARSET=utf8; |
| |
| # 使用全文索引查询 |
| SELECT * FROM papers WHERE MATCH(title,content) AGAINST (‘查询字符串’); |
| |
| 1. 使用全文索引前,搞清楚版本支持情况; |
| 2. 全文索引比 like + % 快 N 倍,但是可能存在精度问题; |
| 3. 如果需要全文索引的是大量数据,建议先添加数据,再创建索引。 |
| # 空间索引创建中,要求空间类型的字段必须为非空 |
| CREATE TABLE test5( |
| geo GEOMETRY NOT NULL, |
| SPATIAL INDEX spa_idx_geo(geo) |
| ) ENGINE=MyISAM; |
| # 方式1 ALTER TABLE ... ADD ... |
| CREATE TABLE book5( |
| book_id INT , |
| book_name VARCHAR(100), |
| AUTHORS VARCHAR(100), |
| info VARCHAR(100) , |
| COMMENT VARCHAR(100), |
| year_publication YEAR |
| ); |
| |
| SHOW INDEX FROM book5; |
| |
| ALTER TABLE book5 ADD INDEX idx_cmt(COMMENT); |
| |
| ALTER TABLE book5 ADD UNIQUE uk_idx_bname(book_name); |
| |
| ALTER TABLE book5 ADD INDEX mul_bid_bname_info(book_id,book_name,info); |
| |
| # 方式2 CREATE INDEX ... ON ... |
| CREATE TABLE book6( |
| book_id INT , |
| book_name VARCHAR(100), |
| AUTHORS VARCHAR(100), |
| info VARCHAR(100) , |
| COMMENT VARCHAR(100), |
| year_publication YEAR |
| ); |
| |
| SHOW INDEX FROM book6; |
| |
| 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); |
| # 方式1:ALTER TABLE .... DROP INDEX .... |
| ALTER TABLE book5 |
| DROP INDEX idx_cmt; |
| |
| # 方式2:DROP INDEX ... ON ... |
| DROP INDEX uk_idx_bname ON book5; |
| |
| # 测试:删除联合索引中的相关字段,索引的变化 |
| ALTER TABLE book5 |
| DROP COLUMN book_name; |
- UPDATE、DELETE 的 WHERE 条件列
| 对数据按照某个条件进行查询后再进行 UPDATE 或 DELETE 的操作,如果对 WHERE 字段创建了索引,就能大幅提升效率。 |
| 原理是因为我们需要先根据 WHERE 条件列检索出来这条记录,然后再对它进行更新或删除。如果进行更新的时候,更新的 |
| 字段是非索引字段,提升的效率会更明显,这是因为非索引字段更新不需要对索引进行维护 |
| 有时候我们需要对某个字段进行去重,使用 DISTINCT,那么对这个字段创建索引,也会提升查询效率。 |
| 连接表的数量尽量不要超过 3 张 |
| 对 WHERE 条件创建索引 |
| 对用于连接的字段创建索引 ,并且该字段在多张表中的 类型必须一致 |
| # 创建一张商户表,因为地址字段比较长,在地址字段上建立前缀索引 |
| create table shop(address varchar(120) not null); |
| |
| alter table shop add index(address(12)); |
| |
| # 截切合适的长度作为前缀 |
| count(distinct left(列名, 索引长度))/count(*) |
| |
| select count(distinct address) / count(*) from shop; |
| |
| # 数值越接近1越合适 |
| select count(distinct left(address,10)) / count(*) as sub10, |
| count(distinct left(address,15)) / count(*) as sub11, |
| count(distinct left(address,20)) / count(*) as sub12, |
| count(distinct left(address,25)) / count(*) as sub13 |
| from shop; |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
2021-06-11 java和js中for循环的区别
2021-06-11 js函数和封装