索引特性
1.索引:
1.1作用:
索引在數據庫中的作用與目錄在書籍中的作用類似,都是用來提高查找信息的速度。索引提高數據庫的性能,不用加內存,不用修改程序,不用調sql,只要執行正確的create index
,查詢的速度就可以提高成百上千倍。因此索引的價值在於提高一個海量數據的檢索速度。
1.2代價:查詢速度提高是以數據修改操作(插入、更新、刪除)的速度爲代價的,這些寫操作,增加了大量的IO。另外索引還會在硬盤上佔用相當大的空間。(以空間換時間)
2.索引分類:
- 主鍵索引(primary key)
- 唯一索引(unique)
- 普通索引(index)
- 全文索引(fulltext)
3.索引基本原理
基於一張海量數據表分別進行查詢
- 未使用索引查詢
mysql> select * from emp where empno=998877;
+--------+--------+----------+------+---------------------+---------+--------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+--------+--------+----------+------+---------------------+---------+--------+--------+
| 998877 | eAnNbS | SALESMAN | 0001 | 2019-07-26 00:00:00 | 2000.00 | 400.00 | 105 |
+--------+--------+----------+------+---------------------+---------+--------+--------+
1 row in set (5.41 sec)
可以看出耗時爲5.41秒,這還只是在本機一個人操作的情況下
- 使用索引查詢
mysql> alter table EMP add index(empno);
mysql> select * from emp where empno=123456;
+--------+--------+----------+------+---------------------+---------+--------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+--------+--------+----------+------+---------------------+---------+--------+--------+
| 123456 | JYWOee | SALESMAN | 0001 | 2019-07-26 00:00:00 | 2000.00 | 400.00 | 88 |
+--------+--------+----------+------+---------------------+---------+--------+--------+
1 row in set (0.01 sec)
在數據庫中查找數據時,存在兩種方法:第一種就是全表掃描,即查找所需要的數據要從表的第一條記錄開始掃描,一直到表的最後一條記錄(上述中的未使用索引查詢語句結果);第二種方法:使用索引查詢,添加字段索引後,索引會形成一顆二叉樹,採用二分查找的思想,對於8000000,最多隻查找23次。
4.創建索引
4.1創建主鍵索引
- 第一種方式:在創建表時,直接在字段名後指定primary key
create table user1(id int primary key,name varchar(20));
- 第二種方式:在創建表的最後,指定某列爲主鍵索引
create table user2(id int,name varchar(20), primary key(id));
- 第三種方式:創建表後再添加主鍵
create table user3(id int,name varchar(20));
alter table user3 add primary key(id);
主鍵索引的特點:
- 一張表中,最多有一個主鍵索引
- 主鍵索引的效率高(主鍵不可重複)
- 創建主鍵索引的列,它的值不能爲null,且不能重複
- 主鍵索引的列基本上都是int型
4.2唯一索引的創建
- 第一種方式:在定義表時,在某列後面指定unique唯一屬性
create table user4(id int primary key,name varchar(20) unique);
- 第二種方式:創建表時,在表的後面指定某列或者某幾列爲unique
create table user5(id int primary key,name varchar(20),unique(name));
- 第三種方式:創建表後再添加唯一索引
create table user6(id int primary key,name varchar(20));
alter table user6 add unqiue(name);
唯一索引的特點:
- 一個表中可以有多個唯一索引
- 查詢效率高
- 如果在某一列建立唯一索引,必須保證該列不能有重複數據
- 如果一個唯一索引上指定not null,等價於主鍵索引
4.3普通索引的創建
- 第一種方式:在表的最後定義,指定某列爲索引
create table user8(id int primary key,
name varchar(20),
email varchar(30),
index(name)
);
- 第二種方式:創建完表後指定某列爲普通索引
create table8(id int primary key,
name varchar(20),
email varchar(30)
);
alter table user8 add index(name);
- 第三種方式:創建一個索引名爲idx_name的索引
create table user9(id int primary key,
name varchar(20),
email varchar(30)
);
create index idx_name on user9(name);
普通索引特點:
- 一張表可以有多個普通索引,它在實際開發中使用較多
- 如果某列需要創建索引,但是該列有重複值時,就要使用普通索引
4.4全文索引
當對文章字段或有大量文字的字段進行檢索時,會使用到全文索引。MySQL提供全文索引機制,要求表的存儲引擎必須是MyISAM,而且默認的全文檢索支持英文,不支持中文。如果對中文進行全文檢索,可以使用sphinx的中文版(coreseek)
--創建表
mysql> CREATE TABLE articles (
-> id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
-> title VARCHAR(200),
-> body TEXT,
-> FULLTEXT (title,body)
-> )engine=MyISAM;
Query OK, 0 rows affected (0.03 sec)
--添加記錄
mysql> INSERT INTO articles (title,body) VALUES
-> ('MySQL Tutorial','DBMS stands for DataBase ...'),
-> ('How To Use MySQL Well','After you went through a ...'),
-> ('Optimizing MySQL','In this tutorial we will show ...'),
-> ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
-> ('MySQL vs. YourSQL','In the following database comparison ...'),
-> ('MySQL Security','When configured properly, MySQL ...');
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0
- 查詢有沒有’database’數據
如果使用如下的查詢方式,雖然查詢出數據,但是沒有使用到全文索引
mysql> select * from articles where body like '%database%';
+----+-------------------+------------------------------------------+
| id | title | body |
+----+-------------------+------------------------------------------+
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
| 5 | MySQL vs. YourSQL | In the following database comparison ... |
+----+-------------------+------------------------------------------+
通過explain工具查看key,確定是否使用到全文索引
mysql> explain select * from articles where body like '%database%'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: articles
partitions: NULL
type: ALL
possible_keys: NULL
~~key: NULL~~ ==>key爲null,表示沒有用到索引
key_len: NULL
ref: NULL
rows: 6
filtered: 16.67
Extra: Using where
1 row in set, 1 warning (0.00 sec)
- 採用以下方式使用全文索引
mysql> select * from articles
-> where match(title,body) against('database');
+----+-------------------+------------------------------------------+
| id | title | body |
+----+-------------------+------------------------------------------+
| 5 | MySQL vs. YourSQL | In the following database comparison ... |
| 1 | MySQL Tutorial | DBMS stands for DataBase ... |
+----+-------------------+------------------------------------------+
使用explain工具分析這個sql語句
mysql> explain select * from articles where match(title,body) against('database')\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: articles
partitions: NULL
type: fulltext
possible_keys: title
~~key: title~~ ==>key爲建表時定義的全文索引字段
key_len: 0
ref: const
rows: 1
filtered: 100.00
Extra: Using where
1 row in set, 1 warning (0.00 sec)
5.查詢索引
- 第一種方法:
show keys from table_name
mysql> show keys from articles\G
*************************** 1. row ***************************
Table: articles ==>表名
Non_unique: 0 ==>0表示唯一索引
Key_name: PRIMARY ==>主鍵索引
Seq_in_index: 1
Column_name: id ==>索引在哪個字段
Collation: A
Cardinality: 6
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE ==>以二叉樹形式的索引
Comment:
Index_comment:
- 第二種方法:
show index from table_name;
- 第三種方法:
desc table_name;
mysql> desc articles\G
*************************** 1. row ***************************
Field: id
Type: int(10) unsigned
Null: NO
Key: PRI
Default: NULL
Extra: auto_increment
6.刪除索引
-
刪除主鍵索引
alter table table_name drop primary key;
-
刪除其他索引
alter table table_name drop index 索引名
索引名就是show keys from 表名中的 key_name字段 -
刪除索引
drop index 索引名 on table_name
mysql> drop index title on articles;
Query OK, 6 rows affected (0.02 sec)