18嫂易、MySQL索引(基礎(chǔ))

一、概要

索引就像一本書的目錄掐禁。而當(dāng)用戶通過索引查找數(shù)據(jù)時怜械,就好比用戶通過目錄查詢某章節(jié)的某個知識點。這樣就幫助用戶有效地提高了查找速度穆桂。所以宫盔,使用索引可以有效地提高數(shù)據(jù)庫系統(tǒng)的整體性能

在我們的一個應(yīng)用系統(tǒng)中,讀寫的比例一般大概8:2左右,在實戰(zhàn)開發(fā)中,當(dāng)數(shù)據(jù)量比較大的時候查詢的速度比較慢的時候,我們可以通過創(chuàng)建索引的方式來加快我們的查詢速度

二享完、什么叫索引

系統(tǒng)根據(jù)某種算法,將已有的數(shù)據(jù)(未來可能新增的數(shù)據(jù))有额,單獨建立一個文件般又,這個文件能夠?qū)崿F(xiàn)快速匹配數(shù)據(jù)彼绷,并且能夠快速的找到對應(yīng)的記錄,本質(zhì)上是一種數(shù)據(jù)結(jié)構(gòu)

三、優(yōu)缺點

1茴迁、優(yōu)點

  • 提升查詢數(shù)據(jù)的效率
  • 可以加速表與表之間的連接
  • 在使用分組和排序進行檢索的時候寄悯,可以減少查詢中分組和排序的時間

2、缺點

  • 當(dāng)對表中的數(shù)據(jù)進行增加堕义、刪除和修改的時候猜旬,索引也要動態(tài)的維護,這樣就降低了數(shù)據(jù)的維護速度倦卖。
  • 創(chuàng)建索引和維護索引要耗費時間洒擦,這種時間隨著數(shù)據(jù)量的增加而增加。
  • 索引需要占物理空間怕膛,除了數(shù)據(jù)表占數(shù)據(jù)空間之外熟嫩,每一個索引還要占一定的物理空間,如果要建立聚簇索引褐捻,那么需要的空間就會更大掸茅。

三、索引分類

1柠逞、按存儲結(jié)構(gòu)

  1. BTree索引
  2. Hash索引
  3. 位圖索引(mysql不支持)

2 昧狮、按應(yīng)用層次

  1. 普通索引,
  2. 主鍵索引
  3. 唯一索引
  4. 全文索引
  5. 復(fù)合索引

3板壮、數(shù)據(jù)行的物理順序與列值的邏輯順序相同

  1. 聚集索引
  2. 非聚集索引

四逗鸣、基本使用

4.1、主鍵索引

  1. 說明

    創(chuàng)建主鍵約束自動會建立主鍵索引个束,不允許重復(fù)慕购,不允許空值

  2. 語法格式

    -- 創(chuàng)建主鍵時數(shù)據(jù)庫自動創(chuàng)建
    CREATE TABLE 表名 (
      列名 類型  PRIMARY KEY
    )
    -- 或者 表級創(chuàng)建
    CREATE TABLE 表名 (
      列名 類型 ,
       PRIMARY KEY(列名)
    )
    
  3. 示例代碼

    CREATE TABLE t_test(
         -- 自動創(chuàng)建主鍵索引
         tid int AUTO_INCREMENT  PRIMARY KEY
    )
    -- 或者
    CREATE TABLE t_test(
         -- 自動創(chuàng)建主鍵索引
         tid int AUTO_INCREMENT ,
         PRIMARY KEY(tid)
    )
    

4.2茬底、普通索引

  1. 說明

    在創(chuàng)建普通索引時沪悲,不附加任何限制條件。這類索引可以創(chuàng)建在任何數(shù)據(jù)類型中阱表,其值是否唯一和非空由字段本身的完整性約束條件決定殿如。

  2. 語法格式

    -- 在創(chuàng)建表的時候創(chuàng)建  (不推薦)
    CREATE TABLE 表名(
         列名 類型 約束,
         ....,
         key ()
    )
    --  創(chuàng)建表之后在創(chuàng)建索引 (推薦方式創(chuàng)建)
    CREATE INDEX 索引名 ON 表 (列名,);
    
  3. 示例代碼

    CREATE TABLE t_index_key
    (
        tid  int PRIMARY KEY AUTO_INCREMENT,
        name varchar(64) NOT NULL,
        KEY (name)
    )
    
    -- 刪除索引
    DROP INDEX name ON t_index_key
    -- 創(chuàng)建索引 推薦
    CREATE  INDEX  idx_key_name ON t_index_key(name)
    -- 查看索引
    EXPLAIN  SELECT * from t_index_key
    WHERE name='123'
    

4.3、唯一索引

  1. 說明

    用來建立索引的列的值必須是唯一的最爬,允許空值, 可以通過創(chuàng)建表的時候使用唯一約束創(chuàng)建

  2. 語法格式

    CREATE  UNIQUE INDEX 索引名 ON  表名(列名 DESC,列名)
    
  3. 示例代碼

    CREATE  UNIQUE INDEX idx_user_username
    ON t_user(username DESC)
    

4.4涉馁、全文索引

  1. 說明

    即為全文索引,Mysql5.6之前只有MyISAM引擎支持爱致,Mysql5.6之后InnoDB也支持烤送。目前只有 CHAR、VARCHAR 糠悯,TEXT 列上可以創(chuàng)建全文索引

    主要解決 它的出現(xiàn)是為了解決WHERE name LIKE “%word%"這類針對文本的模糊查詢效率較低的問題

  2. 創(chuàng)建格式

    -- 1. 創(chuàng)建表
    DROP TABLE IF EXISTS t_myisam;
    CREATE TABLE t_myisam
    (
        mid    int AUTO_INCREMENT PRIMARY KEY,
        name   varchar(64) NOT NULL,
        detail text
    ) ENGINE = MYISAM
      DEFAULT CHARSET = UTF8MB4;
      
    
  3. 查詢格式

     MATCH (列名,...) AGAINST ('查詢的關(guān)鍵字')
    
  4. 示例代碼

    -- 1. 創(chuàng)建
    DROP TABLE IF EXISTS t_myisam;
    
    CREATE TABLE t_myisam
    (
        mid    int AUTO_INCREMENT PRIMARY KEY,
        name   varchar(64) NOT NULL,
        detail text
    
    ) ENGINE = MYISAM
      DEFAULT CHARSET = UTF8MB4;
    
    --  2.創(chuàng)建全文索引
    CREATE FULLTEXT  INDEX idx_username_detail
    ON  t_myisam(detail)
    
    --  查看索引信息
    SHOW INDEX FROM t_myisam
    --  或者
    SHOW  KEYS  FROM  t_myisam
    
    SELECT *
            FROM t_myisam
            WHERE  MATCH(detail) AGAINST('%ab%')
    -- 查看索引是否生效
    
    EXPLAIN SELECT *
            FROM t_myisam
            WHERE  MATCH(detail) AGAINST('%ab%')
    

4.5帮坚、聯(lián)合索引(多列索引)

  1. 說明

    聯(lián)合索引遵守“最左前綴”原則妻往,即在查詢條件中使用了聯(lián)合索引的第一個字段,索引才會被使用试和。因此讯泣,在聯(lián)合索引中索引列的順序至關(guān)重要。如果不是按照索引的最左列開始查找阅悍,則無法使用索引

  2. 語法格式

    CREATE INDEX  索引名 ON 表名(索引字段,索引字段,...)
    
  3. 示例代碼

    CREATE TABLE t_user
    (
        uid         int         AUTO_INCREMENT PRIMARY KEY,
        username    varchar(64)                            NOT NULL,
        password    varchar(128)                        NOT NULL,
        phone       varchar(11)                         NOT NULL,
        is_delete   tinyint   DEFAULT 0                 NOT NULL,
        create_date timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
        CONSTRAINT index_user_name
            UNIQUE (username)
    );
    
    --  創(chuàng)建普通的聯(lián)合索引
    CREATE INDEX index_user_date
        ON t_user (username,phone,create_date);
    
    -- 聯(lián)合索引字段 username,phone,create_date
    
    -- 1. 可以
    SELECT *
    FROM t_user
    WHERE username = 'admin';
    -- 2. 可以
    SELECT *
    FROM t_user
    WHERE username = 'admin'
      AND phone = '123456';
    -- 3. 可以
    SELECT *
    FROM t_user
    WHERE username = 'admin'
      AND phone = '123456'
      AND create_date = '2019-07-18 17:04:12';
    
    -- 不可以
    SELECT *
    FROM t_user
    WHERE phone = '123456';
    
    
  4. 最左前綴的原則

    • 如果我們建立了一個2列的聯(lián)合索引(a,b),實際上已經(jīng)相當(dāng)于建立了兩個聯(lián)合索引( a ) 好渠、( a, b );
    • 如果有一個3列索引( a, b, c ),實際上已經(jīng)建立了三個聯(lián)合索引( a )节视、(a, b)拳锚、(a, b, c)。依次內(nèi)推
  5. 總結(jié)

    當(dāng)創(chuàng)建(a,b,c)聯(lián)合索引時肴茄,相當(dāng)于創(chuàng)建了(a)單列索引晌畅,(a,b)聯(lián)合索引以及(a,b,c)聯(lián)合索引
    想要索引生效的話,只能使用 a和a,b和a,b,c三種組合;當(dāng)然寡痰,測試過抗楔,a,c組合也可以

五、什么情況使用索引

  1. 索引應(yīng)該經(jīng)常建在where 子句經(jīng)常用到的列上拦坠。如果某個大表經(jīng)常使用某個字段進行查詢连躏,并且檢索行數(shù)小于總表行數(shù)的5%。則應(yīng)該考慮贞滨。
  2. 對于兩表連接的字段入热,應(yīng)該建立索引。如果經(jīng)常在某表的一個字段進行Order By 則也經(jīng)過進行索引晓铆。
  3. 不應(yīng)該在小表上建設(shè)索引(例如表中只有三四個字段)勺良。

六、索引失效的情況

  1. 對索引列運算骄噪,運算包括(+尚困、-、*链蕊、/事甜、!滔韵、%)逻谦,導(dǎo)致索引失效

    -- 則會使索引失效,
    EXPLAIN SELECT * FROM tbl WHERE  age + 5 > 10 
    
  2. 不等于(!=)比較特殊 除主鍵索引或索引是整數(shù)類型外的其它索引都失效

    EXPLAIN SELECT *
            FROM t_user
            WHERE username != 'OlUldQDIVV';
    -- 索引有效
    EXPLAIN SELECT * FROM t_user WHERE uid != 1;
    
  3. like以通配符開頭(‘%’),如果非要用使用全文索引

  4. 如果條件中有or陪蜻,即使其中有條件帶索引也不會使用 如果想使用or邦马,又想讓索引生效,只能將or條件中的每個列都加上索引

  5. 小于 大于這個根據(jù)實際查詢數(shù)據(jù)來判斷,如果全盤掃描速度比索引速度要快則不走索引 勇婴。

  6. 索引列上不要使用函數(shù),oracle必須使用函數(shù)索引

    -- 索引失效
    SELECT * FROM t_user WHERE substr(username ,1 ,3 ) = 'ABC' 
    
    

總結(jié)一句話就是, 使用explain 關(guān)鍵執(zhí)行一下 key是否有值, 有值就說明走了索引,null就表示索引失效

七忱嘹、key和index區(qū)別

1嘱腥、說明

key 是數(shù)據(jù)庫的物理結(jié)構(gòu)耕渴,它包含兩層意義,一是約束(偏重于約束和規(guī)范數(shù)據(jù)庫的結(jié)構(gòu)完整性)齿兔,二是索引(輔助查詢用的)橱脸。包括primary key, unique key, foreign key

2、primary key

  1. 一是約束作用(constraint)分苇,用來規(guī)范一個存儲主鍵和唯一性添诉,
  2. 同時也在此key上建立了一個index

3、 unique key

  1. 約束作用(constraint)医寿,規(guī)范數(shù)據(jù)的唯一性
  2. 在這個key上建立了一個index

4栏赴、foreign key

  1. 約束作用(constraint),規(guī)范數(shù)據(jù)的引用完整性
  2. 在這個key上建立了一個index

七靖秩、總結(jié)

  1. 能用唯一索引须眷,一定用唯一索引
  2. 可以給字段加非空約束就盡量加上非空約束
  3. 聯(lián)合索引的順序不同,影響索引的選擇沟突,盡量將值少的放在前面
  4. 千萬不要給大字段加索引

八 花颗、其它

1、查看索引

  1. 語法

    show index from tblname;
    -- 或者
    show keys from tblname;
    
  2. 說明

    • Non_unique:如果索引不能包括重復(fù)詞惠拭,則為0扩劝。如果可以,則為1
    • Key_name:索引的名稱
    • Column_name:索引列名稱
    • Index_type :索引類型
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末职辅,一起剝皮案震驚了整個濱河市棒呛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌域携,老刑警劉巖簇秒,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異涵亏,居然都是意外死亡宰睡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門气筋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拆内,“玉大人,你說我怎么就攤上這事宠默◆锘校” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長抹沪。 經(jīng)常有香客問我刻肄,道長,這世上最難降的妖魔是什么融欧? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任敏弃,我火速辦了婚禮,結(jié)果婚禮上噪馏,老公的妹妹穿的比我還像新娘麦到。我一直安慰自己,他們只是感情好欠肾,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布瓶颠。 她就那樣靜靜地躺著,像睡著了一般刺桃。 火紅的嫁衣襯著肌膚如雪粹淋。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天瑟慈,我揣著相機與錄音桃移,去河邊找鬼。 笑死封豪,一個胖子當(dāng)著我的面吹牛谴轮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吹埠,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼第步,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了缘琅?” 一聲冷哼從身側(cè)響起粘都,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刷袍,沒想到半個月后翩隧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡呻纹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年堆生,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雷酪。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡淑仆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出哥力,到底是詐尸還是另有隱情蔗怠,我是刑警寧澤墩弯,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站寞射,受9級特大地震影響渔工,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜桥温,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一引矩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧策治,春花似錦脓魏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽混蔼。三九已至履腋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間惭嚣,已是汗流浹背遵湖。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留晚吞,地道東北人延旧。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像槽地,于是被迫代替她去往敵國和親迁沫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355