1. 程式人生 > >Mysql DBA 高級運維學習筆記-索引知識及創建索引的多種方法實戰

Mysql DBA 高級運維學習筆記-索引知識及創建索引的多種方法實戰

varchar not 要求 相關 auto 唯一索引 cte lte 推薦

本文是我學習老男孩老師的Mysql DBA 高級運維課程的學習筆記,老男孩老師講的很好,非常感謝老男孩老師。剛剛接觸運維有很多不懂得知識,如果我發表的文章有不正確的地方,請運維行業的精英,老師及時指點,呵呵~ 後面我還會更新自己學習ysql DBA 高級運維課程的學習筆記。

9.9.7 為表的字段創建索引

索引就像書的目錄一樣,如果在字段上建立索引,那麽以索引為條件時可以加快查詢數據的速度。

9.9.7.1 創建主鍵索引

查詢數據庫的內容,按主鍵查詢是最快的,每個表只能有一個主鍵,但是可以有多個普通索引列,主鍵列要求所有內容必須唯一,而索引列不要求內容唯一。
我們無論建立主鍵索引還是普通索引,都要在表的對應列上創建,可以對單列創建索引也可以對多列創建索引

建立主鍵索方法:

1.在創建表時,可以增加建立主鍵索引語句

system@ceshi 04:0932->create table student(
-> id int(4) not null AUTO_INCREMENT,
-> name char(20) not null,
-> age tinyint(2) NOT NULL default ‘0‘,
-> dept varchar(16) default NULL,
-> primary key(id),
-> KEY index_name(name)
-> );

提示:

a.AUTO_INCREMENT 自增

b.Primary key(id) 主鍵

c.KEY index_name(name) name 字段普通索引

操作演示

system@ceshi 04:2146->drop table student;
Query OK, 0 rows affected (0.00 sec)
system@ceshi 04:2333->create table student(
-> id int(4) not null AUTO_INCREMENT,
-> name char(20) not null,
-> age tinyint(2) NOT NULL default ‘0‘,
-> dept varchar(16) default NULL,
-> primary key(id),
-> KEY index_name(name)
-> );
Query OK, 0 rows affected (0.00 sec)
system@ceshi 04:2609->desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type| Null | Key | Default | Extra  |
+-------+-------------+------+-----+---------+----------------+
| id| int(4)  | NO   | PRI | NULL| auto_increment |
| name  | char(20)| NO   | MUL | NULL||
| age   | tinyint(2)  | NO   | | 0   ||
| dept  | varchar(16) | YES  | | NULL||
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

提示:PRI為主鍵的標識,MUL為普通索引的標識。

2.建立表之後通過alter命令增加主鍵索引(不推薦這種做法)

a.主鍵列不能重復創建,必須先刪除上面的配置

system@ceshi 04:3716->alter table student drop primary key;

b.建表時忘記加主鍵了利用alter命令增加id列為自增主鍵列

system@ceshi 04:5948->alter table student change id id int primary key auto_increment;
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
system@ceshi 05:0324->desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type| Null | Key | Default | Extra  |
+-------+-------------+------+-----+---------+----------------+
| id| int(11) | NO   | PRI | NULL| auto_increment |
| name  | char(20)| NO   | MUL | NULL||
| age   | tinyint(2)  | NO   | | 0   ||
| dept  | varchar(16) | YES  | | NULL||
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

提示:只有int類型且為primary key才可以使用auto_increment。

9.9.7.2 創建普通索引

1.在建表時,可以增加建立普通索引列的語句如下:

system@ceshi 04:0932->create table student(
-> id int(4) not null AUTO_INCREMENT,
-> name char(20) not null,
-> age tinyint(2) NOT NULL default ‘0‘,
-> dept varchar(16) default NULL,
-> primary key(id),
-> KEY index_name(name)
-> );

提示:

a.KEY index_name(name)name 字段普通索引

操作演示:

system@ceshi 04:2146->drop table student;
Query OK, 0 rows affected (0.00 sec)
system@ceshi 04:2333->create table student(
-> id int(4) not null AUTO_INCREMENT,
-> name char(20) not null,
-> age tinyint(2) NOT NULL default ‘0‘,
-> dept varchar(16) default NULL,
-> primary key(id),
-> KEY index_name(name)
-> );
Query OK, 0 rows affected (0.00 sec)
system@ceshi 04:2609->desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type| Null | Key | Default | Extra  |
+-------+-------------+------+-----+---------+----------------+
| id| int(4)  | NO   | PRI | NULL| auto_increment |
| name  | char(20)| NO   | MUL | NULL||
| age   | tinyint(2)  | NO   | | 0   ||
| dept  | varchar(16) | YES  | | NULL||
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

2.建表後利用alter增加普通索引

刪除建表時創建的index_name索引

system@ceshi 05:0333->alter table student drop index index_name;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
system@ceshi 06:0419->desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type| Null | Key | Default | Extra  |
+-------+-------------+------+-----+---------+----------------+
| id| int(11) | NO   | PRI | NULL| auto_increment |
| name  | char(20)| NO   | | NULL||
| age   | tinyint(2)  | NO   | | 0   ||
| dept  | varchar(16) | YES  | | NULL||
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

在name列上添加索引,索引名為index_name

system@ceshi 06:0431->alter table student add index index_name(name);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

system@ceshi 06:0456->desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type| Null | Key | Default | Extra  |
+-------+-------------+------+-----+---------+----------------+
| id| int(11) | NO   | PRI | NULL| auto_increment |
| name  | char(20)| NO   | MUL | NULL||
| age   | tinyint(2)  | NO   | | 0   ||
| dept  | varchar(16) | YES  | | NULL||
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

9.9.7.3 對字段的前n個字符創建普通索引

當遇到表中比較大的列時,列內容的前n個字符在所有內容中已經接近唯一時,這時可以對列的前n個字符建立索引而無需對整個列建立索引,這樣可以節省創建索引占用的系統空間,以及降低和更新維護消耗的系統資源。

對字段的前n個字符創建索引的語法:

Create index index_name on test(name(8)); 條件列前n個字符創建索引

實戰操作:

system@ceshi 06:0838->create index index_dept on student(dept(8));
Query OK, 0 rows affected (0.19 sec)
Records: 0  Duplicates: 0  Warnings: 0

system@ceshi 06:3650->desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type| Null | Key | Default | Extra  |
+-------+-------------+------+-----+---------+----------------+
| id| int(11) | NO   | PRI | NULL| auto_increment |
| name  | char(20)| NO   | MUL | NULL||
| age   | tinyint(2)  | NO   | | 0   ||
| dept  | varchar(16) | YES  | MUL | NULL||
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
system@ceshi 06:3847->show index from student\G
*************************** 1. row ***************************
   Table: student
  Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
 Column_name: id
   Collation: A
 Cardinality: 0
Sub_part: NULL
  Packed: NULL
Null: 
  Index_type: BTREE
 Comment: 
*************************** 2. row ***************************
   Table: student
  Non_unique: 1
Key_name: index_name
Seq_in_index: 1
 Column_name: name
   Collation: A
 Cardinality: NULL
Sub_part: NULL
  Packed: NULL
Null: 
  Index_type: BTREE
 Comment: 
*************************** 3. row ***************************
   Table: student
  Non_unique: 1
Key_name: index_dept
Seq_in_index: 1
 Column_name: dept
   Collation: A
 Cardinality: NULL
Sub_part: 8
  Packed: NULL
Null: YES
  Index_type: BTREE
 Comment: 
3 rows in set (0.00 sec)

9.9.7.4 為表的多個字段創建聯合索引

如果查詢的條件是多列時,我們可以為多個查詢的列創建聯合索引,甚至可以為多列的前n個字符創建聯合索引,實戰演示如下:

為多個列創建索引

system@ceshi 06:4019->create index ind_name_dept on student(name,dept);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

system@ceshi 06:4726->show index from student\G
*************************** 1. row ***************************
   Table: student
  Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
 Column_name: id
   Collation: A
 Cardinality: 0
Sub_part: NULL
  Packed: NULL
Null: 
  Index_type: BTREE
 Comment: 
*************************** 2. row ***************************
   Table: student
  Non_unique: 1
Key_name: index_name
Seq_in_index: 1
 Column_name: name
   Collation: A
 Cardinality: NULL
Sub_part: NULL
  Packed: NULL
Null: 
  Index_type: BTREE
 Comment: 
*************************** 3. row ***************************
   Table: student
  Non_unique: 1
Key_name: index_dept
Seq_in_index: 1
 Column_name: dept
   Collation: A
 Cardinality: NULL
Sub_part: 8
  Packed: NULL
Null: YES
  Index_type: BTREE
 Comment: 
*************************** 4. row ***************************
   Table: student
  Non_unique: 1
Key_name: ind_name_dept
Seq_in_index: 1
 Column_name: name
   Collation: A
 Cardinality: NULL
Sub_part: NULL
  Packed: NULL
Null: 
  Index_type: BTREE
 Comment: 
*************************** 5. row ***************************
   Table: student
  Non_unique: 1
Key_name: ind_name_dept
Seq_in_index: 2
 Column_name: dept
   Collation: A
 Cardinality: NULL
Sub_part: NULL
  Packed: NULL
Null: YES
  Index_type: BTREE
 Comment: 
5   rows in set (0.00 sec)

可以對多個列的前n個字符創建聯合索引,實戰演示如下:

system@ceshi 06:5144->drop index ind_name_dept on student; 刪除索引的另一種方法。
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

system@ceshi 06:5158->create index ind_name_dept on student(name(8),dept(10));
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

提示:

按條件列查詢數據時,聯合索引是有前綴生效特性的

Index(a,b,c)僅a,ab,abc三個查詢條件可以走索引。b,bc,ac,c不能走索引

9.9.7.5 創建唯一索引(非主鍵索引)

Create unique index index_age on student(age);

唯一索引是用來約束表的內容的,不能重復。

system@ceshi 07:0828->create unique index uni_ind_name on student(name);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
system@ceshi 07:1010->desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type| Null | Key | Default | Extra  |
+-------+-------------+------+-----+---------+----------------+
| id| int(11) | NO   | PRI | NULL| auto_increment |
| name  | char(20)| NO   | UNI | NULL||
| age   | tinyint(2)  | NO   | | 0   ||
| dept  | varchar(16) | YES  | MUL | NULL||
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

9.9.7.6 索引表的創建及生效條件

問題1:既然索引可以加快查詢速度,那麽是不是就要給所有的列創建索引呢?

解答:因為索引你不但占用系統空間,更新數據庫時還需要維護索引數據。因此索引是一把雙刃劍,並不是越多越好,例如:數十到幾百行的小表上無需創建索引,更新頻繁,讀取少的業務要少建立索引。

問題2:需要在哪些列上創建索引呢?

解答:Select user,host from mysql.user where host= ….索引一定要創建在where後的條件列上,而不是select後的選擇數據的列上,另外我們要盡量選擇在唯一值多的大表上建立索引。創建索引要和開發商量。

9.9.7.7 創建索引命令集合小結

1.創建索引相關命令集合

創建主鍵索引

alter table student change id id int primary key auto_increment;

刪除主鍵索引

alter table student drop primary key

創建普通索引

alter table student add index index_dept(dept(8))

根據列的前n個字符創建索引

create index index_dept on student(dept(8))

根據多個列創建聯合索引

create index ind_name_dept on student(name,dept);

根據多個列的前n個字符創建索引

create index ind_name_dept on student(name(8),dept(10));

刪除普通索引

Alter table student drop index index_dept
drop index ind_name_dept on student

創建唯一索引

create unique index uni_ind_name on student(name);

基本索引:

a.要在表的列上創建索引。

b.索引會加快查詢速度,但是會影響更新的速度,因為要維護索引。

c.索引不是越多越好,要在頻繁查詢的where後的條件列上創建索引。

d.小表或唯一值極少的列上不建索引,要在大表以及不同內容多的列上創建索引。

Mysql DBA 高級運維學習筆記-索引知識及創建索引的多種方法實戰