MySQL之索引(索引作用與代價、分類、基本操作)

索引特性

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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章