就是這么一個結構極其簡單的表,200萬數(shù)量級的復雜查詢將會變的非常緩慢,比如執(zhí)行下面的SQL語句。
SELECT a.id,FROM_UNIXTIME(a.time)
FROM article AS a
WHERE a.title=‘PHP筆試題和答案——基礎語言方面’
查詢時間基本上需要50-100秒,這個是非常恐怖的,如果加上聯(lián)合查詢和其他一些約束條件,數(shù)據(jù)庫會瘋狂的消耗內存。
如果這時候數(shù)據(jù)庫里面針對title字段建立了索引,查詢效率將會大幅度提升,如下圖所示。可見對于大型數(shù)據(jù)庫,建立索引是非常非常重要的一個優(yōu)化手段(當然還會有很多其他優(yōu)化這樣的數(shù)據(jù)庫的方法,但是本文主題所限,暫不討論。),廢話了這么多,以下開始總結MySQL中索引的使用方法和性能優(yōu)化以及一些注意事項。
索引是一種特殊的文件(InnoDB數(shù)據(jù)表上的索引是表空間的一個組成部分),它們包含著對數(shù)據(jù)表里所有記錄的引用指針。更通俗的說,數(shù)據(jù)庫索引好比是一本書前面的目錄,能加快數(shù)據(jù)庫的查詢速度。上述SQL語句,在沒有索引的情況下,數(shù)據(jù)庫會遍歷全部200條數(shù)據(jù)后選擇符合條件的;而有了相應的索引之后,數(shù)據(jù)庫會直接在索引中查找符合條件的選項。如果我們把SQL語句換成“SELECT * FROM article WHERE id=2000000”,那么你是希望數(shù)據(jù)庫按照順序讀取完200萬行數(shù)據(jù)以后給你結果還是直接在索引中定位呢?上面的兩個圖片鮮明的用時對比已經(jīng)給出了答案(注:一般數(shù)據(jù)庫默認都會為主鍵生成索引)。
索引分為聚簇索引和非聚簇索引兩種,聚簇索引是按照數(shù)據(jù)存放的物理位置為順序的,而非聚簇索引就不一樣了;聚簇索引能提高多行檢索的速度,而非聚簇索引對于單行的檢索很快。
1. 普通索引
這是最基本的索引,它沒有任何限制,比如上文中為title字段創(chuàng)建的索引就是一個普通索引。
–直接創(chuàng)建索引
CREATE INDEX indexName ON table(column(length))
–修改表結構的方式添加索引
ALTER tableADD INDEX indexName ON (column(length))
–創(chuàng)建表的時候同時創(chuàng)建索引
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` int(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
INDEX indexName (title(length))
)
–刪除索引
DROP INDEX indexName ON table
2. 唯一索引
與普通索引類似,不同的就是:索引列的值必須唯一,但允許有空值(注意和主鍵不同)。如果是組合索引,則列值的組合必須唯一,創(chuàng)建方法和普通索引類似。
–創(chuàng)建唯一索引
CREATE UNIQUE INDEX indexName ON table(column(length))
–修改表結構
ALTER table ADD UNIQUE indexName ON (column(length))
–創(chuàng)建表的時候直接指定
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` int(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
UNIQUE indexName (title(length))
);