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;