like索引查詢--mysql索引

like '%%'如何命中索引

相信各位老鐵在開發(fā)的過程中肯定都遇到過like全匹配的需求货徙。在數(shù)據(jù)量很小的時候惠桃,select * from user where name like '%hello%'扣墩。這種查詢問題也不大族跛,但是久而久之弛作,會發(fā)現(xiàn)輸入框再輸入這種簡單文字的時候頁面就會loading很久愕提。當(dāng)數(shù)據(jù)量大起來馒稍,like雙百分號匹配不走索引的時候就很憂傷,但是需求不會因為這個而改變浅侨。那么纽谒,mysql是如何解決這個問題的呢?或許可以試試explain select name from user where name like '%hello%'如输。你會意外的發(fā)現(xiàn)key字段竟然不是null鼓黔。W-H-Y?

覆蓋索引

這里引入一個概念不见。索引包含所有滿足查詢需要的數(shù)據(jù)的索引澳化,稱為覆蓋索引(Covering Index)。百度百科來的定義稳吮、是不是抽象的一臉懵逼缎谷?可以簡單的理解為select的數(shù)據(jù)列只用從索引中就能夠取得,不需要查數(shù)據(jù)就能拿到結(jié)果盖高。拿這個栗子來說慎陵,name字段自身是建立了索引的(innodb引擎下索引自身是保存了數(shù)據(jù)的)眼虱,select查詢name字段直接就可以獲取到值喻奥,就不需要再根據(jù)索引去數(shù)據(jù)表里面查對應(yīng)的值。


B+Tree數(shù)據(jù)結(jié)構(gòu).jpg

B+Tree數(shù)據(jù)結(jié)構(gòu)簡介

這里有必要介紹一下mysql -- innodb引擎下B+Tree索引的數(shù)據(jù)結(jié)構(gòu)捏悬。

  1. 淺藍(lán)色的塊是磁盤塊撞蚕,對應(yīng)硬件上的磁盤空間。其中深藍(lán)色的塊表示數(shù)據(jù)項(17过牙,35)甥厦,黃色的表是指針(P1,P2,P3)
  2. 真實的數(shù)據(jù)存在于葉子節(jié)點(diǎn)中,非葉子節(jié)點(diǎn)只儲存數(shù)據(jù)項和指引方向的指針寇钉,這里17刀疙,和35并不實際存在于數(shù)據(jù)表中。
  3. 如果我們要在上圖中搜索數(shù)據(jù)75扫倡,磁盤僅需要3次IO即可谦秧。第一次,與17和35比較,發(fā)現(xiàn)數(shù)據(jù)大于35疚鲤,根據(jù)指針P3指示繼續(xù)往下走锥累。第二次,發(fā)現(xiàn)數(shù)據(jù)介于65和87中間集歇,指針P2指向數(shù)據(jù)塊10桶略,那么第三次就能直接查找到數(shù)據(jù)。
  4. 顯然如果沒有建立索引诲宇,直接挨個查找75的IO次數(shù)遠(yuǎn)不止3次际歼。

關(guān)于like的索引問題

索引失效的幾種情況大家可以先預(yù)習(xí)一下,這是百度上搜到的http://blog.csdn.net/zmx729618/article/details/52701370姑蓝,如果覺得沒必要蹬挺,可以直接跳過。下面我們來模擬數(shù)據(jù)它掂。

CREATE TABLE `user` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(125) NOT NULL DEFAULT '' COMMENT '名稱',
  `age` int(3) unsigned NOT NULL DEFAULT '0' COMMENT '年齡',
  `address` varchar(50) NOT NULL DEFAULT '' COMMENT '住址',
  `deleted` tinyint(4) unsigned DEFAULT NULL,
  `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_name_age_address` (`name`,`age`,`address`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COMMENT='用戶表測試';
INSERT INTO `user` (`id`, `name`, `age`, `address`, `deleted`, `created`)
VALUES
    (1, '5', 1000, '花果山', 0, '2017-12-10 21:48:03'),
    (2, '8', 800, '高老莊', 0, '2017-12-10 21:48:16'),
    (3, '3', 25, '長安', 0, '2017-12-10 21:48:49'),
    (4, '白龍馬', 700, '龍宮', 0, '2017-12-10 21:49:16');

執(zhí)行上面的建表語句巴帮,初始化數(shù)據(jù)之后,我們來看一下下面的兩個sql


select * from user 
where name = '3' and age = 20 and address like '長安%' 

select * from user 
where name like 3 and age > 20 and address like '長安%'  

然后分析一波下面的問題

  1. 第二個查詢語句有沒有命中索引虐秋?
  2. 如果沒有命中索引榕茧,如何讓它命中索引
  3. 它能命中索引的哪些字段(name,age,address)
    .
    .
    .
    .
    .
    .

好了,思考一個省略號的時間之后我們來回答這個問題客给。

  1. 第二個sql命中了索引用押。
  2. 這里name字段是varchar類型,字符串未加單引號索引會失效靶剑,但是like特殊蜻拨,不受限制,這里加不加單引號并沒有影響桩引。
  3. 命中了索引的字段是缎讼,name、age坑匠。 address并未命中血崭。這里name字段like查詢?yōu)榉秶樵儯凑章?lián)合索引返回查詢之后全失效的規(guī)則厘灼,這里age本不應(yīng)該命中索引夹纫,但是like例外。

下面是分析過程
我們分析的依據(jù)是第一個sql的執(zhí)行結(jié)果设凹,用explain來分析查看舰讹,可以看到3個字段都命中索引之后 key_len值為708。


sql1.jpg

再看第二個sql闪朱,發(fā)現(xiàn)key_len為506月匣⌒僬觯可以證明真正命中了索引的字段是name和age。


sql2.jpg

今天就分析到這里桶错,希望這些例子能幫助大家少踩一些坑:剿簟!院刁!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末糯钙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子退腥,更是在濱河造成了極大的恐慌任岸,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狡刘,死亡現(xiàn)場離奇詭異享潜,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)嗅蔬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進(jìn)店門剑按,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人澜术,你說我怎么就攤上這事艺蝴。” “怎么了鸟废?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵猜敢,是天一觀的道長。 經(jīng)常有香客問我盒延,道長缩擂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任添寺,我火速辦了婚禮胯盯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘畦贸。我一直安慰自己陨闹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布薄坏。 她就那樣靜靜地躺著,像睡著了一般寨闹。 火紅的嫁衣襯著肌膚如雪胶坠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天繁堡,我揣著相機(jī)與錄音沈善,去河邊找鬼乡数。 笑死,一個胖子當(dāng)著我的面吹牛闻牡,可吹牛的內(nèi)容都是我干的净赴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼罩润,長吁一口氣:“原來是場噩夢啊……” “哼玖翅!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起割以,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤金度,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后严沥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體猜极,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年消玄,在試婚紗的時候發(fā)現(xiàn)自己被綠了跟伏。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡翩瓜,死狀恐怖酬姆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奥溺,我是刑警寧澤辞色,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站浮定,受9級特大地震影響相满,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜桦卒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一立美、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧方灾,春花似錦建蹄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嘿棘,卻和暖如春劲腿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸟妙。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工焦人, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挥吵,地道東北人。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓花椭,卻偏偏與公主長得像忽匈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子矿辽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,442評論 2 359

推薦閱讀更多精彩內(nèi)容