百木园-与人分享,
就是让自己快乐。

MySQL基础_索引

MySQL 索引(入门):

一、介绍

  1.什么是索引?

  一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句的优化显然是重中之重。说起加速查询,就不得不提到索引了。

  2.为什么要有索引呢?

    引在MySQL中也叫做“键”,是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能
    非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要。
    索引优化应该是对查询性能优化最有效的手段了。索引能够轻易将查询性能提高好几个数量级。
    索引相当于字典的音序表,如果要查某个字,如果不使用音序表,则需要从几百页中逐页去查。

  3.主要优点:

    索引大大减小了服务器需要扫描的数据量,从而大大加快数据的检索速度,这也是创建索引的最主要的原因。

    可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。

    在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。

  4.缺点:

    创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
    索引需要占物理空间,除了数据表占用数据空间之外,每一个索引还要占用一定的物理空间。
    表中的数据进行增、删、改的时候,索引也要动态的维护,这就降低了整数的维护速度
    对于非常小的表,大部分情况下简单的全表扫描更高效

二、索引的本质

   索引原理:索引的目的在于提高查询效率,与我们查阅图书所用的目录是一个道理:先定位到章,然后定位到该章下的一个小节,然后找到页数。相似的例子还有:查字典,查火车车次,飞机航班等

  索引本质:通过不断地缩小想要获取数据的范围来筛选出最终想要的结果,同时把随机的事件变成顺序的事件,也就是说,有了这种索引机制,我们可以总是用同一种查找方式来锁定数据。

 

三、MySQL的索引分类

1.普通索引 index :加速查找

2.唯一索引  与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须是唯一的,创建方法和普通索引类似。 主键索引:primary key加速查找+约束(不为空且唯一) 唯一索引:unique:加速查找+约束 (唯一)
3.联合索引(组合索引)  
平时用的SQL查询 语句一般都有比较多的限制条件,所以为了进一步榨取MySQL的效率,就要考虑建立组合索引
    -primary key(id,name):联合主键索引
    -unique(id,name):联合唯一索引
    -index(id,name):联合普通索引
4.全文索引 fulltext :用于搜索很长一篇文章的时候,效果最好。
5.空间索引 spatial :了解就好,几乎不用

  案例:

CREATE DATABASE IF NOT EXISTS info DEFAULT CHARSET utf8;
USE info;
# 创建表
CREATE TABLE IF NOT EXISTS emp(emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(20),
salary INT,
dept_id INT,
manager_id INT
);

# 插入数据
INSERT INTO emp (emp_name,salary,dept_id,manager_id)VALUES
(\"张三\",1000,1,1),
(\"李四\",2000,1,1),
(\"王五\",5000,2,3),
(\"林青霞\",8000,3,6),
(\"风清扬\",6000,5,4),
(\"花无缺\",10000,5,5),
(\"景天\",14000,8,7),
(\"赵敏\",17000,8,7);
# 给一个列的每个值 创建单独标记 利用索引创建的这些标记可以进行一个排序,更快查询 
SELECT * FROM emp WHERE emp_name = \"李四\";

# 1.1 创建索引:单独创建索引
CREATE INDEX index_name ON emp(emp_name);
SELECT * FROM emp WHERE emp_name = \"李四\";

# 1.2 创建索引:修改表结构创建索引
ALTER TABLE emp ADD INDEX index_salary(salary);

# 1.3 创建索引:创建表时,创建索引
CREATE TABLE IF NOT  EXISTS article(id INT NOT NULL AUTO_INCREMENT,
title VARCHAR(30) NOT NULL,
content VARCHAR(50),
dt DATE,
PRIMARY KEY(id),
INDEX index_title(title)
);

# 2 删除索引
DROP INDEX index_name ON emp;

# 3.1 唯一索引:索引标记的列的值必须唯一
CREATE UNIQUE INDEX index_name ON emp(emp_name);

# 3.2 修改表时创建唯一索引
ALTER TABLE article ADD UNIQUE INDEX index_content(content);

# 3.3 创建表时创建唯一索引
CREATE TABLE IF NOT EXISTS test (id INT NOT NULL AUTO_INCREMENT ,
tname VARCHAR(20) NOT NULL,
age INT NOT NULL,
s_id INT NOT NULL,
PRIMARY KEY (id),
UNIQUE INDEX index_id(s_id)
) 
 
# 4.1 单独创建组合索引
CREATE INDEX index_ct ON article(content,dt);
 SELECT * FROM article WHERE content=\'123\' AND dt = \"2020-10-10\"

# 4.2 修改表结构时创建组合结构
ALTER TABLE test  ADD INDEX index_to(tname,age);

# 4.3 创建表时创建组合索引
CREATE TABLE IF NOT  EXISTS test02(id INT NOT NULL AUTO_INCREMENT,
tname VARCHAR(20) NOT NULL,
age INT NOT NULL,
s_id INT NOT NULL,
PRIMARY KEY (id),
UNIQUE INDEX index_to(s_id,id)
)

 

四、复合索引

  一列的索引称为单列索引,多列的称为复合索引,因为BTREE索引是顺序排列的,所以比较适合范围查询,但是在复合索引中,还应注意列数目、列的顺序以及前面范围查询的列对后边列的影响。

# 建表
create
table staffs( id int primary key auto_increment, name varchar(24) not null default \'\' comment \'姓名\', age int not null default 0 comment \'年龄\', pos varchar(20) not null default \'\' comment \'职位\', add_time timestamp not null default current_timestamp comment \'入职时间\' ) charset utf8 comment \'员工记录表\';

# 添加三列的复合索引
alter table staffs add index idx_nap(name, age, pos);

#1. 全值匹配
select * from staffs where name = \'July\' and age = \'23\' and pos = \'dev\' ;

#2. 匹配最左列 对于复合索引来说,不总是匹配所有字段列,但是可以匹配索引中靠左的列。
select * from staffs where name = \'July\' and age = \'23\';
# key字段显示用到了索引,注意,key_len字段(表示本次语句使用的索引长度)数值比上一条小了,意思是它并未使用全部索引列,事实上只用到了name和age列

#3. 匹配列前缀
select * fromstaffs where name like \'J%\';
# 即一个索引中列的前一部分,主要用在模糊匹配

#4. 匹配范围
select * from staffs where name > \'Mary\';

#5. 精确匹配一列并范围匹配右侧相邻列
select * from staffs where name = \'July\' and age > 25;
# 即前一列是固定值,后一列是范围值,它用了name与age两个列的索引(key_len推测)

#6. 只访问索引的查询

 select name,age,pos from staffs where name = \'July\' and age = 25 and pos = \'dev\';

 select name,age from staffs where name = July and age > 25;

 # 比如staffs表的情况,索引建立在(name,age,pos)上面,前面一直是读取的全部列,如果我们用到了哪些列的索引,查询时也只查这些列的数据,就是只访问索引的查询

 

 


来源:https://www.cnblogs.com/zzc1102/p/16029955.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » MySQL基础_索引

相关推荐

  • 暂无文章