1、引入索引的问题
在图书馆查找一本书的过程,可类比数据库查询场景。在一般软件系统中,对数据库操作以查询为主,数据量较大时,优化查询是关键,索引便是优化查询的重要手段 。
2、索引是什么
索引是一种特殊文件,包含对数据表所有记录的引用指针,类似书的目录,能加快查询速度 。
其核心特点:
- 是帮助 MySQL 高效获取数据的数据结构
- 存储在文件系统中
- 文件存储形式与存储引擎有关
- 有特定的文件结构
3、索引为什么选择 B + 树
(1)可选数据结构及特点
可作为索引的数据结构有 hash表
、二叉树
、b树
、b + 树
,不同结构特点如下:
hash 表缺点
- 存储需将所有数据文件加载到内存,浪费空间
- 等值查询快,但实际工作中范围查询更多,hash 不适用
(2)B + 树优势(结合场景选择,文档未详细展开,可理解为综合适配数据库查询需求 )
B + 树在范围查询、数据存储效率、树结构高度(影响查询次数 )等方面表现更优,适合作为 MySQL 索引结构 。
4、测试索引(完整流程)
(1)创建数据库
在 MySQL 中创建 test_indexdb
数据库,操作:
mysql> create database test_indexdb;
Query OK, 1 row affected (0.01 sec)
(2)创建数据表
在 test_indexdb
中创建 test_index
表,操作:
mysql> use test_indexdb;
Database changed
mysql> create table test_index(title varchar(20));
Query OK, 0 rows affected (0.01 sec)
(3)插入测试数据(C 程序实现)
编写 C 程序向表中插入 1 万条字符串数据,代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <mysql/mysql.h> int main()
{ MYSQL mysql_conn; MYSQL *mysql = mysql_init(&mysql_conn); if (mysql == NULL) { printf("init err\n"); exit(1); } mysql = mysql_real_connect(mysql,"localhost","root","Abc_111111","test_indexdb",3306,NULL,0); if (mysql == NULL) { printf("connect err\n"); exit(1); } char sql_buff[128] = {0}; for( int i = 0;i < 10000; i++ ) { sprintf(sql_buff,"insert into test_index values('test-%d')",i); if (mysql_query(mysql,sql_buff) != 0 ) { printf("insert into err\n"); break; } } mysql_close(mysql);
}
编译与运行:
# 编译(链接 MySQL 客户端库)
stu@stu-virtual-machine:~/mysql_dir$ gcc -o test_index test_index.c -lmysqlclient # 运行程序插入数据
stu@stu-virtual-machine:~/mysql_dir$ ./test_index
# 执行时大约需要10秒时间
(4)查询验证(对比索引效果)
① 开启运行时间监测
set profiling=1;
② 查找数据(无索引时)
查找 title='test-9999'
的数据,语句:
select * from test_index where title='test-9999';
③ 查看执行时间
show profiles;
④ 创建索引
为 test_index
表的 title
列创建索引,语句:
create index title_index on test_index(title(20));
⑤ 再次查询并查看时间
执行查询语句:
select * from test_index where title='test-9999';
查看执行时间:
show profiles;
⑥ 结果对比(示例,以实际执行为准 )
mysql> show profiles;
+----------+------------+----------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+----------------------------------------------------+
| 1 | 0.00681275 | select * from test_index where title='test-9999' |
| 2 | 0.00067400 | show create table test_index |
| 3 | 0.08281450 | create index t_index on test_index(title(20)) |
| 4 | 0.00071700 | select * from test_index where title='test-9999' |
| 5 | 0.00045275 | show create table test_index |
| 6 | 0.00930825 | drop index t_index on test_index |
| 7 | 0.00841750 | select * from test_index where title='test-9999' |
| 8 | 0.05149600 | create index t_index on test_index(title(20)) |
| 9 | 0.00043150 | select * from test_index where title='test-9999' |
+----------+------------+----------------------------------------------------+
可观察到,创建索引后查询时长(如 Query_ID=4、9 )明显缩短。
⑦ 删除索引
若需删除创建的索引,语句:
drop index t_index on test_index;