索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。
索引的作用就相当于书的目录。打个比方: 我们在查字典的时候,如果没有目录,那我们就只能一页一页的去找我们需要查的那个字,速度很慢。如果有目录了,我们只需要先去目录里查找字的位置,然后直接翻到那一页就行了。
索引底层数据结构存在很多种类型,常见的索引结构有: B 树, B+树 和 Hash、红黑树。在 MySQL 中,无论是 Innodb 还是 MyIsam,都使用了 B+树作为索引结构。
优点:
- 提高查询效率:索引可以显著减少查询时需要扫描的数据行数,从而加快查询速度
- 支持排序和分组:索引可以加快ORDER BY和GROUP BY的操作速度,因此MySQL可以利用索引来快速定位到排序和分组的数据。
- 加快表的连接:索引可以加快表与表之间的连接,尤其是在实现数据的参考完整性方面
- 查询优化:使用索引可以在查询过程中使用优化器,提高系统的性能
缺点:
- 时间成本:创建和维护索引需要时间,且随着数据量的增加,这种时间成本也会增加。
- 空间成本:索引也需要占用物理空间,数据量越大,所需的空间也越大。
- 降低更新效率:索引在表的增删改操作时需要动态维护,这可能会降低数据的维护速度。
单列索引是在表的一个列上创建索引。它可以提高查询性能,尤其是在对该列进行搜索,排序和分组时。
单列索引有下面三个类型:
- 普通索引:最基本的索引类型,没有唯一性限制
- 唯一索引:索引的值必须是唯一的,但允许有空值
- 主键索引:主键自动创建一个唯一索引
下面是普通索引的一些操作:
create table empleyees (
id int auto_increment PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
email VARCHAR(100),
department VARCHAR(50),
salary DECIMAL(10,2)
);
insert into empleyees (first_name,last_name,email,department,salary) VALUES
('张三', '李四', '[email protected]', '技术部', 8000),
('王五', '赵六', '[email protected]', '市场部', 9000);
-- 创建单列索引
CREATE INDEX idx_email on empleyees(email);
-- 查看索引
show index from empleyees;
-- 使用索引查询
SELECT* FROM empleyees where email ='zhangsan@company';
都知道索引查询能提高速度,那到底提高了多少呢?我们这里举个例子:
DELIMITER $$
CREATE PROCEDURE populate_employees()
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i < 1000 DO
INSERT INTO empleyees(id, first_name, last_name, email, department, salary)
VALUES
(NULL, -- id is auto-increment so we leave it as NULL
CONCAT('First', i),
CONCAT('Last', i),
CONCAT('email', i, '@example.com'),
CONCAT('Department', i),
50000.00); -- 假设一个默认薪水,你可以根据需要调整
SET i = i + 1;
END WHILE;
END$$
CALL populate_employees();
-- 无索引查询
SELECT* from empleyees where first_name=30;
-- 创建索引
CREATE INDEX index_text on empleyees(first_name);
EXPLAIN SELECT* from empleyees where first_name=30;
在`EXPLAIN`输出中,“Extra”列将告诉你是否使用了索引。如果看到“Using index”,则表示使用了索引。同时,`rows`列显示了MySQL估计需要扫描的行数,通常有索引时这个数字会明显降低,从而加快查询速度。
唯一索引要求索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。主键索引是一种特殊的唯一索引,不允许有空值。
演示一下过程:
CREATE table user1(
id int auto_increment primary key,
name VARCHAR(50) not null,
email VARCHAR(100) not null UNIQUE
);
-- 插入数据
INSERT into user1(name,email)
VALUES('Alice','xxxx.com');
INSERT into user1(name,email)
VALUES('Bob','bob.com');
向这个表中插入数据,运行一下
主键索引:是一种特殊的唯一索引&