人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動態(tài)

MySQL索引下推詳細(xì)

發(fā)布日期:2022-02-06 12:47 | 文章來源:腳本之家


索引下推(ICP)是針對MySQL使用索引從表中檢索數(shù)據(jù)行的情況的優(yōu)

  • 在沒有索引下推的情況下,MySQL通過存儲引擎遍歷索引來定位表中的數(shù)據(jù)行并將它們返回給MySQl服務(wù)器,服務(wù)器再進(jìn)行WHERE條件的判斷,確認(rèn)是否將數(shù)據(jù)行加入結(jié)果集。
  • 開啟索引下推,且WHERE條件部分可以僅使用索引中的列來評估,這時MySQL服務(wù)器會將這部分WHERE條件下推到存儲引擎,接著存儲引擎使用索引條目評估推送的索引條件,僅當(dāng)滿足該條件時才從表中進(jìn)行讀取

索引下推可以減少存儲引擎訪問數(shù)據(jù)表的次數(shù)以及MySQL服務(wù)器訪問存儲引擎的次數(shù)。

是不是還有點懵呢,那就對了,毫無疑問上面這段話理解起來相當(dāng)費勁,但請不要灰心,我將用最通俗易懂的語言來帶你了解索引下推。

總結(jié)一下:

  • 最左前綴原則
  • 回表

1、最左前綴原則

  MySQL在建立聯(lián)合索引時會遵循最左前綴原則,比如現(xiàn)在User表建立了聯(lián)合索引(id,name,age)根據(jù)最左前綴原則只有在SQL的條件部分命中(id)、(id,name)或者(id, name, age)時才能使用到這個聯(lián)合索引。

能使用該索引的情況如下:

SELECT * FROM USER WHERE id = 1
SELECT * FROM USER WHERE id = 1 and name = 'zhangsan'
SELECT * FROM USER WHERE id = 1 and name = 'zhangsan' and age = 18

不能使用該索引的情況如下:

SELECT * FROM USER WHERE name = 'zhangsan'
SELECT * FROM USER WHERE age = 18
SELECT * FROM USER WHERE name = 'zhangsan' and age = 18

對于聯(lián)合索引mysql會一直向右匹配直到遇到范圍查詢(>、<、between、like)就停止匹配。

2、回表

MySQLInnoDB引擎下支持兩種索引

  • 聚集索引 :索引里(B+樹的葉子結(jié)點上)存儲的是數(shù)據(jù)行(真實的數(shù)據(jù))
  • 普通索引 :索引里(B+樹的葉子結(jié)點上)存儲的是主鍵

這里著重說一下聚集索引,官方文檔有以下描述

  • 在有主鍵的表,InnoDB將主鍵作為聚集索引
  • 沒有主鍵的表,InnoDB使用第一個唯一索引作為聚集索引
  • 即沒有主鍵也沒有唯一索引時,MySQL將生成一個隱藏的6字節(jié)大小的row ID字段作為聚集索引

  MySQL通過普通索引沒法一次性將數(shù)據(jù)拿全的情況下,通過普通索引獲取主鍵值,再通過主鍵值到聚集索引中定位到記錄,這個過程就叫回表。可以通過建立覆蓋索引來減少回表,比如現(xiàn)在要通過身份證號查姓名,那就建立身份證號和姓名的聯(lián)合索引(id,name),當(dāng)查詢時可以通過這個索引直接拿到姓名name得值,不再需要去聚集索引里查找了,這就是覆蓋索引。

3、索引下推

首先創(chuàng)建一個用戶表

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255)  DEFAULT NULL,
  `age` int  DEFAULT 0,
  `class` varchar(255)  DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_two` (`name`,`age`)
) ENGINE=InnoDB;
//這張表增加一個復(fù)合索引
 (`name`,`age`)

給表插入數(shù)據(jù)

INSERT INTO  `student` (`name`, `age`, `class`) VALUES  ('pengpeng', 21, '1');
INSERT INTO  `student` (`name`, `age`, `class`) VALUES  ('pengpeng', 22, '2');
INSERT INTO  `student` (`name`, `age`, `class`) VALUES  ('pengpeng', 23, '3');
INSERT INTO  `student` (`name`, `age`, `class`) VALUES  ('pengpeng', 24, '4');
INSERT INTO  `student` (`name`, `age`, `class`) VALUES  ('pengpeng', 25, '5');

查詢插入的數(shù)據(jù)如下

接下來explain下面這個SQL

explain select * from student where name like 'peng%' and age = 23;

可以看到Extra字段顯示為USING INDEX CONDITION,這就表明這個SQL使用了索引下推,我們分析下上面這個SQL語句:

在MySQL5.6之前,只能從name字段中找出符合條件的行然后開始回表,到聚集索引上找出數(shù)據(jù)行,再對age字段進(jìn)行對比,把符合條件的數(shù)據(jù)加入到結(jié)果集中。

在MySQL5.6引入了索引下推優(yōu)化,在索引的遍歷過程中,對索引中包含字段先做判斷,這里對age字段進(jìn)行判斷。直接將age字段不滿足的數(shù)據(jù)行排除,從而減少回表的次數(shù)。

問答區(qū)

問題1 當(dāng)復(fù)合索引列為(name,age,address)時 以下SQL能使用索引嗎?

select * from student where name like 'peng%' and age = 23;

  可以,遇到like會中斷后續(xù)元素的匹配,但只能使用name這個字段,mysql會一直向右匹配直到遇到范圍查詢(>、<、between、like)就停止匹配。范圍列可以用到索引,但是范圍列后面的列無法用到索引。即索引最多用于一個范圍列,因此如果查詢條件中有兩個范圍列則無法全用到索引。

問題2 索引下推只能存在聯(lián)合索引里嗎?

是的,非聯(lián)合索引無法使用索引下推。

問題3 索引下推在哪些情況下無法使用?

下推條件遇到子查詢

下推條件遇到函數(shù)

非InnoDB表和MyISAM表

問題4 索引下推如何開啟和關(guān)閉?

// 索引下推默認(rèn)是開啟的
set optimizer_switch='index_condition_pushdown=off'; // 關(guān)閉
set optimizer_switch='index_condition_pushdown=on'; // 開啟

總結(jié)

  索引下推在非主鍵索引上的優(yōu)化,可以有效減少回表的次數(shù),大大提升了查詢的效率,在平時工作中可以根據(jù)業(yè)務(wù)情況通過優(yōu)化索引來達(dá)到使用索引下推,提高業(yè)務(wù)吞吐量。

到此這篇關(guān)于MySQL索引下推詳細(xì)的文章就介紹到這了,更多相關(guān)MySQL索引下推內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

香港服務(wù)器租用

版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部