7.redis三大特殊資料型別
Mysql-索引
1. 概念
索引是一個排序的列表,在這個列表中儲存著索引的值和包含這個值的資料所在行的實體地址(類似於c語言的連結串列通過指標指向資料記錄的記憶體地址)
使用索引後可以不用掃描全表來定位某行的資料,而是先通過索引表找到該行資料對應的實體地址然後訪問相應的資料,因此能加快資料庫的查詢速度。
索引就好比是一本書的目錄,可以根據目錄中的頁碼快速找到所需的內容。
索引是表中一列或者若干列值排序的方法。
建立索引的目的是加快對錶中記錄的查詢或排序。
2. 作用與副作用
2.1正作用
設定了合適的索引之後,資料庫利用各種快速定位技術,能夠大大加快查詢速度,這是建立索引的最主要的原因。
當表很大或查詢涉及到多個表時,使用索引可以成千.上萬倍地提高查詢速度。
可以降低資料庫的I0成本,並且索引還可以降低資料庫的排序成本。
通過建立唯一性索引,可以保證資料表中每一行資料的唯一性。
可以加快表與表之間的連線。
在使用分組和排序時,可大大減少分組和排序的時間。
建立索引在搜尋和恢復資料庫中的資料時能顯著提高效能。
2.2副作用
索引的副作用:
●索引需要佔用額外的磁碟空間。
對於MyISAM 引擎而言,索引檔案和資料檔案是分離的,索引檔案用於儲存資料記錄的地址。而InnoDB 引擎的表資料檔案本身就是索引檔案。
●在插入和修改資料時要花費更多的時間,因為索引也要隨之變動。
3. 建立原則
索引雖可以提升資料庫查詢的速度,但並不是任何情況下都適合建立索引。因為索引本身會消耗系統資源,在有索引的情況下,資料庫會先進行索引查詢,然後定位到具體的資料行,如果索引使用不當,反而會增加資料庫的負擔。
●表的主鍵、外來鍵必須有索引。因為主鍵具有唯--性,外來鍵關聯的是主表的主鍵,查詢時可以快速定位。
●記錄數超過300行的表應該有索引。如果沒有索引,每次查詢都需要把表遍歷一遍,會嚴重影響資料庫的效能。
●經常與其他表進行連線的表,在連線欄位上應該建立索引。
●唯一性太差的欄位不適合建立索引。
●更新太頻繁地欄位不適合建立索引。
●經常出現在where子句中的欄位,特別是大表的欄位,應該建立索引。
●在經常進行GROUP BY、 ORDER BY的欄位上建立索引;
●索引應該建在選擇性高的欄位上(值唯一性)
●索引應該建在小欄位上,對於大的文字欄位甚至超長欄位,不要建索引。
4.索引分類
4.1 普通索引
基本索引,沒有唯一性的限制
建立方式:
-
直接建立
CREATE INDEX 索引名 ON 表名(列名[ (length)]);
(列名(length)): length是可選項, 下同。如果忽略length 的值,則使用整個列的值作為索引。如果指定,使用列的前length個字元來建立索引,這樣有利於減小索引檔案的大小。在不損失精確性的情況下,長度越短越好。
索引名建議以“_index"結尾。
-
修改表方式建立
ALTER TABLE 表名 ADD INDEX 索引名(列名) ;
-
建立表時指定索引
CREATE TABLE 表名(欄位1資料型別,欄位2資料型別[,...], INDEX索引名(列名));
4.2 唯一索引
與普通索引類似,但區別是唯一索引列的每個值都唯一。
唯一索引允許有空值(注意和主鍵不同)。如果是用組合索引建立,則列值的組合必須唯一。新增唯一鍵將自動建立唯索引。
建立方式:
-
直接建立
直接建立唯一索引:
CREATE UNIQUE INDEX 索引名 ON 表名(列名) ;
-
修改表結構
修改表方式建立
ALTER TABLE 表名ADD UNIQUE 索引名(列名) ;
-
建立表方式
建立表的時候指定
CREATE TABLE表名(欄位1 資料型別,欄位2資料型別[...],UNIQUE索引名(列名));
4.3 主鍵索引
主鍵索引:是一種特殊的唯一索引, 必須指定為“PRIMARY KEY”。一個表只能有一個主鍵,不允許有空值。新增主鍵將自動建立主鍵索引。
4.4 組合(索引)
組合索引(單列索引與多列索引) :可以是單列上建立的索引,也可以是在多列上建立的索引。需要滿足最左原則,因為select 語句的where條件是依次從左往右執行的,所以在使用select 語句查詢時where條件使用的欄位順序必須和組合索引中的排序一致,否則索引將不會生效。
-
建立
CREATE TABLE表名(列名1資料型別,列名2資料型別,列名3資料型別, INDEX索引名(列名1, 列名2,列名3));
查詢時使用索引。
select * from表名where 列名1='...' AND 列名 2='...' AND列名3='...';
聚集索引與非聚集索引
聚集索引也稱為聚簇索引,在聚集索引中,表中行的物理順序與鍵值的邏輯(索引)順序相同。一個表只能包含一個聚集索引, 即如果存在聚集索引,就不能再指定CLUSTERED 關鍵字。
非聚集索引也叫非簇索引,在非聚集索引中,資料庫表中記錄的物理順序與索引順序可以不相同。一個表中只能有一個聚集索引,但表中的每一列都可以有自己的非聚集索引。
4.5 全文索引
全文索引(FULLTEXT) :適合在進行模糊查詢的時候使用,可用於在一篇文章中檢索文字資訊。
在MySQL5.6 版本以前FULLTEXT索引僅可用於MyISAM引擎警,在5.6 版本之後innodb 引擎也支援FULLTEXT索引。
全文索引可以在CHAR、VARCHAR或者TEXT 型別的列上建立。每個表一般只有一個全文索引
5. 索引的其他相關命令
刪除索引
DROP INDEX <索引名> ON <表名>
ALTER TABLE <表名> DROP INDEX <索引名>;
查詢索引
show index from <表名>;
show keys from <表名>;
各欄位的含義如下:
Table:表的名稱。
Non unique: 如果索引不能包括重複詞,則為0;如果可以,則為1。
Key_name:索引的名稱。
Seq_in_index:索引中的列序號,從1開始。
Column_name:列名稱。
Collation:列以什麼方式儲存在索引中。在MySQL中,有值ASC'(升序)或NULL (無分類)。
Cardinality:索引中唯一值數目的估計值。
Sub_part:如果列只是被部分地編入索引,則為被編入索引的字元的數目。如果整列被編入索引,則為NULL。
Packed:指示關鍵字如何被壓縮。如果沒有被壓縮,則為NULL。
Null:如果列含有NULL, 則含有YES。如果沒有,則該列含有NO。
Index_ type: 用過的索引方法( BTREE,FULLTEXT,HASH, RTREE) 。
Comment:備註。
分析索引的使用
- explain <select語句>
6.索引速度測試
現有一個employee表,資料有300024條。
mysql> select count(*) from employees;
+----------+
| count(*) |
+----------+
| 300024 |
+----------+
1 row in set (0.03 sec)
檢視該表的索引。有一個主鍵索引emp_no。
mysql> show index from employees;
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| employees | 0 | PRIMARY | 1 | emp_no | A | 299202 | NULL | NULL | | BTREE | | |
+-----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
檢視emp_no id在20023和20043之間的資料。
mysql> select * from employees where emp_no between 20023 and 20043;
+--------+------------+------------+-------------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date |
+--------+------------+------------+-------------+--------+------------+
| 20023 | 1952-02-09 | Nahla | Jervis | M | 1991-08-10 |
| 20024 | 1954-09-23 | Martine | Kambil | M | 1986-05-06 |
| 20025 | 1963-02-13 | Yakkov | Peek | F | 1987-01-31 |
| 20026 | 1953-03-25 | Sanjai | Marrevee | F | 1991-09-23 |
| 20027 | 1957-07-17 | Vidar | Atrawala | M | 1993-04-22 |
| 20028 | 1959-12-25 | Kasidit | Passino | M | 1992-10-04 |
| 20029 | 1964-01-04 | Doowon | Socorro | M | 1991-03-05 |
| 20030 | 1962-05-09 | Nitsan | Hoppenstand | F | 1988-11-18 |
| 20031 | 1962-11-20 | Kenton | Bernini | M | 1985-10-01 |
| 20032 | 1955-11-20 | Cheong | Socorro | M | 1989-04-07 |
| 20033 | 1956-10-10 | Dulce | Azevdeo | F | 1992-11-03 |
| 20034 | 1956-12-03 | Jaques | Baby | M | 1993-07-30 |
| 20035 | 1959-04-25 | Guoxiang | Trogemann | M | 1985-11-11 |
| 20036 | 1963-01-19 | Jaber | Katiyar | M | 1986-08-14 |
| 20037 | 1954-09-07 | Tse | VanScheik | M | 1986-09-24 |
| 20038 | 1962-04-02 | Tremaine | Gente | M | 1992-08-31 |
| 20039 | 1952-06-07 | Udo | Harbusch | F | 1987-09-19 |
| 20040 | 1962-04-16 | Youjian | Vingron | M | 1987-01-21 |
| 20041 | 1952-06-14 | Chikara | Lienhardt | F | 1990-02-23 |
| 20042 | 1955-10-18 | Margareta | Munck | F | 1987-03-23 |
| 20043 | 1952-09-13 | Chikara | Adachi | M | 1985-03-21 |
+--------+------------+------------+-------------+--------+------------+
21 rows in set (0.00 sec)
時間使用0.00 sec
刪除索引。
mysql> ALTER TABLE employees DROP PRIMARY KEY;
Query OK, 300024 rows affected (0.47 sec)
Records: 300024 Duplicates: 0 Warnings: 0
再次執行
mysql> select * from employees where emp_no between 20023 and 20043;
+--------+------------+------------+-------------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date |
+--------+------------+------------+-------------+--------+------------+
| 20023 | 1952-02-09 | Nahla | Jervis | M | 1991-08-10 |
| 20024 | 1954-09-23 | Martine | Kambil | M | 1986-05-06 |
| 20025 | 1963-02-13 | Yakkov | Peek | F | 1987-01-31 |
| 20026 | 1953-03-25 | Sanjai | Marrevee | F | 1991-09-23 |
| 20027 | 1957-07-17 | Vidar | Atrawala | M | 1993-04-22 |
| 20028 | 1959-12-25 | Kasidit | Passino | M | 1992-10-04 |
| 20029 | 1964-01-04 | Doowon | Socorro | M | 1991-03-05 |
| 20030 | 1962-05-09 | Nitsan | Hoppenstand | F | 1988-11-18 |
| 20031 | 1962-11-20 | Kenton | Bernini | M | 1985-10-01 |
| 20032 | 1955-11-20 | Cheong | Socorro | M | 1989-04-07 |
| 20033 | 1956-10-10 | Dulce | Azevdeo | F | 1992-11-03 |
| 20034 | 1956-12-03 | Jaques | Baby | M | 1993-07-30 |
| 20035 | 1959-04-25 | Guoxiang | Trogemann | M | 1985-11-11 |
| 20036 | 1963-01-19 | Jaber | Katiyar | M | 1986-08-14 |
| 20037 | 1954-09-07 | Tse | VanScheik | M | 1986-09-24 |
| 20038 | 1962-04-02 | Tremaine | Gente | M | 1992-08-31 |
| 20039 | 1952-06-07 | Udo | Harbusch | F | 1987-09-19 |
| 20040 | 1962-04-16 | Youjian | Vingron | M | 1987-01-21 |
| 20041 | 1952-06-14 | Chikara | Lienhardt | F | 1990-02-23 |
| 20042 | 1955-10-18 | Margareta | Munck | F | 1987-03-23 |
| 20043 | 1952-09-13 | Chikara | Adachi | M | 1985-03-21 |
+--------+------------+------------+-------------+--------+------------+
21 rows in set (0.06 sec)
已出現時間0.06sec。