22、MySQL索引

一毙玻、概要

索引就像一本書的目錄豌蟋。而當用戶通過索引查找數(shù)據(jù)時,就好比用戶通過目錄查詢某章節(jié)的某個知識點桑滩。這樣就幫助用戶有效地提高了查找速度梧疲。所以运准,使用索引可以有效地提高數(shù)據(jù)庫系統(tǒng)的整體性能

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

二、什么叫索引

系統(tǒng)根據(jù)某種算法胁澳,將已有的數(shù)據(jù)(未來可能新增的數(shù)據(jù))该互,單獨建立一個文件,這個文件能夠實現(xiàn)快速匹配數(shù)據(jù)韭畸,并且能夠快速的找到對應的記錄,本質上是一種數(shù)據(jù)結構

三宇智、優(yōu)缺點

1、優(yōu)點

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

2普筹、缺點

  • 當對表中的數(shù)據(jù)進行增加、刪除和修改的時候隘马,索引也要動態(tài)的維護太防,這樣就降低了數(shù)據(jù)的維護速度。
  • 創(chuàng)建索引和維護索引要耗費時間酸员,這種時間隨著數(shù)據(jù)量的增加而增加蜒车。
  • 索引需要占物理空間,除了數(shù)據(jù)表占數(shù)據(jù)空間之外幔嗦,每一個索引還要占一定的物理空間酿愧,如果要建立聚簇索引,那么需要的空間就會更大邀泉。

四嬉挡、索引分類

1、按存儲結構

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

2 汇恤、按應用層次

  1. 普通索引庞钢,
  2. 主鍵索引
  3. 唯一索引
  4. 全文索引
  5. 復合索引

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

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

五因谎、基本使用

4.1基括、主鍵索引

  1. 說明
    創(chuàng)建主鍵約束自動會建立主鍵索引,不允許重復财岔,不允許空值风皿;
  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 ('查詢的關鍵字' 檢索模式)
    
  4. 搜索語法規(guī)則

    • +一定要有(不含有該關鍵詞的數(shù)據(jù)條均被忽略)袋励。
    • - 不可以有(排除指定關鍵詞侥啤,含有該關鍵詞的均被忽略)。
    • > 提高該條匹配數(shù)據(jù)的權重值
    • * 全匹配茬故,不像其他語法放在前面盖灸,這個要接在字符串后面。
  5. 檢索模式

    • 自然語言檢索: IN NATURAL LANGUAGE MODE
    • 布爾檢索: IN BOOLEAN MODE
      特點如下
      • 不剔除50%以上符合的row磺芭。

      • 不自動以相關性反向排序赁炎。

      • 可以對沒有FULLTEXT index的字段進行搜尋,但會非常慢钾腺。

      • 限制最長與最短的字符串徙垫。

      • 套用Stopwords。

  6. 示例代碼

    -- 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')
     -- 查詢必須包含ab開頭的詞
    SELECT * FROM articles WHERE MATCH (detail) AGAINST ('+ab*'  IN BOOLEAN MODE);   
    

4.5放棒、聯(lián)合索引(多列索引)

  1. 說明
    聯(lián)合索引遵守“最左前綴”原則姻报,即在查詢條件中使用了聯(lián)合索引的第一個字段,索引才會被使用间螟。因此吴旋,在聯(liá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)相當于建立了兩個聯(lián)合索引( a ) 荣瑟、( a, b );
    • 如果有一個3列索引( a, b, c ),實際上已經(jīng)建立了三個聯(lián)合索引( a )溉奕、(a, b)褂傀、(a, b, c)。依次內推
  5. 總結
    當創(chuàng)建(a,b,c)聯(lián)合索引時加勤,相當于創(chuàng)建了(a)單列索引仙辟,(a,b)聯(lián)合索引以及(a,b,c)聯(lián)合索引
    想要索引生效的話,只能使用 a和a,b和a,b,c三種組合同波;當然,我們上面測試過叠国,a,c組合也可以未檩,但實際上只用到了a的索引,c并沒有用到粟焊!

六冤狡、什么情況使用索引

  1. 索引應該經(jīng)常建在where 子句經(jīng)常用到的列上。如果某個大表經(jīng)常使用某個字段進行查詢项棠,并且檢索行數(shù)小于總表行數(shù)的5%悲雳。則應該考慮。
  2. 對于兩表連接的字段香追,應該建立索引合瓢。如果經(jīng)常在某表的一個字段進行Order By 則也經(jīng)過進行索引。
  3. 不應該在小表上建設索引(例如表中只有三四個字段)透典。

七晴楔、索引失效的情況

  1. 對索引列運算,運算包括(+峭咒、-税弃、*、/凑队、则果!、%)顽决,導致索引失效
    -- 則會使索引失效短条,
    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'
    
    總結一句話就是, 使用explain 關鍵執(zhí)行一下 key是否有值, 有值就說明走了索引,null就表示索引失效

八可都、key和index區(qū)別

1、說明

key 是數(shù)據(jù)庫的物理結構蚓耽,它包含兩層意義渠牲,一是約束(偏重于約束和規(guī)范數(shù)據(jù)庫的結構完整性),二是索引(輔助查詢用的)步悠。包括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

九尚粘、總結

  1. 索引占磁盤空間,不要重復的索引敲长,盡量短
  2. 只給常用的查詢條件加索引
  3. 過濾性高的列建索引郎嫁,取值范圍固定的列不建索引
  4. 唯一的記錄添加唯一索引
  5. 頻繁更新的列不要建索引
  6. 不要對索引列運算
  7. 同樣過濾效果下,保持索引長度最小
  8. 合理利用組合索引祈噪,注意索引字段先后順序
  9. 多列組合索引泽铛,過濾性高的字段最前
  10. order by 字段建立索引,
  11. 組合索引钳降,不同的排序順序不能使用索引

十厚宰、其它

1腌巾、查看索引

  1. 語法
    show index from tblname;
    -- 或者
    show keys from tblname;
    
  2. 說明
    • Non_unique:如果索引不能包括重復詞遂填,則為0。如果可以澈蝙,則為1
    • Key_name:索引的名稱
    • Column_name:索引列名稱
    • Index_type :索引類型

2吓坚、執(zhí)行計劃(explain)

  1. 概要
    在 select 語句之前增加 explain 關鍵字,MySQL 會在查詢上設置一個標記灯荧,執(zhí)行查詢時礁击,會返回執(zhí)行計劃的信息,而不是執(zhí)行這條SQL(如果 from 中包含子查詢逗载,仍會執(zhí)行該子查詢哆窿,將結果放入臨時表中)


    image
  2. 主要字段說明
    • type
      system > const > eq_ref > ref > range > index > all
      一般來說,得保證查詢至少達到range級別厉斟,最好能達到ref挚躯。
      index all 性能差需要優(yōu)化 至少要達到 range 級別,要求是 ref 級別擦秽,如果可以是 consts 最好
    • possible_keys
      顯示可能應用在這張表中的索引码荔,一個或多個。查詢涉及到的字段上若存在索引感挥,則該索引將被列出缩搅,但不一定被查詢實際使用
    • key
      實際使用的索引,如果為NULL触幼,則沒有使用索引
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末硼瓣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子置谦,更是在濱河造成了極大的恐慌堂鲤,老刑警劉巖噪猾,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異筑累,居然都是意外死亡袱蜡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門慢宗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坪蚁,“玉大人,你說我怎么就攤上這事镜沽∶粑睿” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵缅茉,是天一觀的道長嘴脾。 經(jīng)常有香客問我,道長蔬墩,這世上最難降的妖魔是什么译打? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮拇颅,結果婚禮上奏司,老公的妹妹穿的比我還像新娘。我一直安慰自己樟插,他們只是感情好韵洋,可當我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著黄锤,像睡著了一般搪缨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鸵熟,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天副编,我揣著相機與錄音,去河邊找鬼旅赢。 笑死齿桃,一個胖子當著我的面吹牛,可吹牛的內容都是我干的煮盼。 我是一名探鬼主播短纵,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼僵控!你這毒婦竟也來了香到?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤悠就,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后梗脾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡炸茧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年瑞妇,在試婚紗的時候發(fā)現(xiàn)自己被綠了梭冠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辕狰。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡控漠,死狀恐怖蔓倍,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情盐捷,我是刑警寧澤偶翅,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布毙驯,位于F島的核電站,受9級特大地震影響爆价,放射性物質發(fā)生泄漏媳搪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一秦爆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧等限,春花似錦、人聲如沸望门。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至哄酝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陶衅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工侠驯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人吟策。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓的止,卻偏偏與公主長得像,于是被迫代替她去往敵國和親诅福。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,724評論 2 354

推薦閱讀更多精彩內容

  • 一赂乐、MySQL優(yōu)化 MySQL優(yōu)化從哪些方面入手: (1)存儲層(數(shù)據(jù)) 構建良好的數(shù)據(jù)結構咖气“ご耄可以大大的提升我們S...
    寵辱不驚丶歲月靜好閱讀 2,431評論 1 8
  • 今天看到一位朋友寫的mysql筆記總結崩溪,覺得寫的很詳細很用心,這里轉載一下伶唯,供大家參考下觉既,也希望大家能關注他原文地...
    信仰與初衷閱讀 4,730評論 0 30
  • 一符欠、概要 索引就像一本書的目錄。而當用戶通過索引查找數(shù)據(jù)時姿染,就好比用戶通過目錄查詢某章節(jié)的某個知識點秒际。這樣就幫助用...
    唯老閱讀 461評論 0 1
  • 索引 數(shù)據(jù)庫中的查詢操作非常普遍,索引就是提升查找速度的一種手段 索引的類型 從數(shù)據(jù)結構角度分 1.B+索引:傳統(tǒng)...
    一凡呀閱讀 2,918評論 0 8
  • 手動不易寄锐,轉發(fā)請注明出處 --Trance 數(shù)據(jù)庫系統(tǒng)命令: (1).查看存儲過程狀態(tài):show pro...
    Trance_b54c閱讀 1,661評論 0 8