自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

為什么SQL查詢以%開頭索引就失效了呢?

數據庫 其他數據庫
覆蓋索引(Covering Index)是一種特殊的索引結構,其設計初衷是為了提高查詢性能。與傳統(tǒng)的索引不同,覆蓋索引包含了查詢所需的所有列,因此,當執(zhí)行查詢時,數據庫引擎可以直接從索引中獲取所需的數據,而無需回表去訪問實際的表數據。

今天我們來聊一下索引失效的問題,因為在開發(fā)的過程中,不光需要我們去寫業(yè)務代碼,有時候還可能會接手一些別人的代碼,而別人寫的一些 SQL ,可能有幾百行,甚至有時候遇到一些時間較久的系統(tǒng),一個完整的 SQL 甚至可能比一個方法都長,這時候,就會出現(xiàn)一種情況,需要你去優(yōu)化,而優(yōu)化的時候,我們就會首先從索引層面下手,這時候,我們就遇到了問題了,比如我們做模糊查詢的時候,很多人的習慣是 LIKE '%xxxx%',殊不知,這種雖然能滿足條件,但是缺忽略了索引,導致索引不生效,今天我們就來說說這個。

建表驗證

如果有些朋友不信的話,那么我們來驗證一下,首先我們建一張表,然后寫入數據,腳本如下:

CREATE TABLE `user`  (
  `ID` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `USER_NAME` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `AGE` int(11) NULL DEFAULT NULL,
  `ADDRESS` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `IP` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `PHONE` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `EMAIL` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`ID`) USING BTREE,
  INDEX `NAME_PHONE`(`USER_NAME`, `PHONE`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

圖片圖片

同時我們給 USER_NAME 和 PHONE 建立了聯(lián)合索引,我們插入數據。

INSERT INTO `baseboot`.`user`(`ID`, `USER_NAME`, `AGE`, `ADDRESS`, `IP`, `PHONE`, `EMAIL`) VALUES ('28715757596573696', '測試人員', 12, '北京市海淀區(qū)', '127.0.0.1', '17788779981', '789911@163.com');
INSERT INTO `baseboot`.`user`(`ID`, `USER_NAME`, `AGE`, `ADDRESS`, `IP`, `PHONE`, `EMAIL`) VALUES ('28715757596573697', '開發(fā)人員', 22, '北京市海淀區(qū)', '127.0.0.1', '17788779981', '789911@163.com');

我們插入兩條數據,接下來我們看看效果。

圖片圖片

然后我們通過 LIKE 來進行查詢。

使用 LIKE '%xxx%'。

圖片圖片

使用 LIKE 'xxx%'。

圖片圖片

我們使用的是 EXPLAN 來分析我們的 SQL ,對比明顯,一個使用了我們創(chuàng)建的索引,另外一個沒有使用我們創(chuàng)建的索引,所以,為什么失效了呢?

為什么 LIKE '%xxxx%' 索引失效了?

當我們遇到這個問題的時候,這個題目也是面試官比較喜歡問到的問題,百分號在左和在右的區(qū)別是哪里呢?

我們都知道在SQL查詢中,LIKE操作符用于模糊匹配字符串。通配符%在LIKE語句中的位置對查詢的性能和結果有著顯著的影響。當%位于LIKE語句的左邊、右邊或兩邊時,它們的行為和效果是不同的。

% 在左邊:

  • 當%位于LIKE語句的左邊時,如LIKE '%keyword',這種查詢模式通常會導致索引失效。因為數據庫系統(tǒng)需要掃描整個表或索引來查找包含指定關鍵詞的記錄,而不是利用索引的有序性來快速定位。這會導致查詢性能下降,尤其是在大型表中。
  • 索引失效的原因是數據庫無法高效匹配這種模式。數據庫難以直接根據索引列的值來定位數據,而需要進行全表掃描或索引的全掃描。

% 在右邊:

  • 當%位于LIKE語句的右邊時,如LIKE 'keyword%',這種查詢模式通??梢岳盟饕绻饕前凑諒淖蟮接业捻樞驑嫿ǖ模ㄈ绯R姷腂+樹索引)。數據庫系統(tǒng)可以從索引的起始位置開始,沿著索引的順序查找以指定關鍵詞開頭的記錄。
  • 雖然索引可以幫助加速查詢,但是如果查詢中還有其他條件或限制,或者如果索引的選擇性較低(即索引中的值大多相同或重復),那么查詢性能可能仍然不如預期。

% 在兩邊:

  • 當%同時位于LIKE語句的左邊和右邊時,如LIKE '%keyword%',這種查詢模式通常也會導致索引失效。因為數據庫系統(tǒng)需要在整個表或索引中查找包含指定關鍵詞的記錄,而無法利用索引的有序性進行快速定位。
  • 與%在左邊的情況類似,這種查詢模式需要進行全表掃描或索引的全掃描,從而導致查詢性能下降。

使 LIKE '%xxx%' 索引生效的操作是什么樣子呢?

那么我們如何讓在左邊的百分號能命中索引,讓索引不失效呢?

我們可以這樣操作:

圖片圖片

也就是說,我們需要把有索引的字段,放在最開始的位置,并且盡量的精確索引的字段,而沒有其他的字段,這種情況也是可以命中索引的。

而這種情況下,其實就可以理解為是覆蓋索引,就是下圖的樣子。

圖片圖片

那么,什么是覆蓋索引呢?

什么是覆蓋索引

覆蓋索引(Covering Index)是一種特殊的索引結構,其設計初衷是為了提高查詢性能。與傳統(tǒng)的索引不同,覆蓋索引包含了查詢所需的所有列,因此,當執(zhí)行查詢時,數據庫引擎可以直接從索引中獲取所需的數據,而無需回表去訪問實際的表數據。

在傳統(tǒng)的索引結構中,索引通常只包含被索引列的值和指向表中對應行的指針。當查詢需要從表中獲取數據時,數據庫引擎首先通過索引找到對應的指針,然后再根據這些指針去表中獲取實際的數據。這個過程被稱為“回表操作”,它增加了查詢的IO操作和數據傳輸的開銷,影響了查詢性能。

而覆蓋索引則避免了回表操作。因為覆蓋索引本身已經包含了查詢所需的所有列的值,所以數據庫引擎在查詢時可以直接從索引中獲取數據,無需再去訪問表。這樣就減少了IO操作和數據傳輸,大大提高了查詢效率。

要創(chuàng)建一個覆蓋索引,需要確保索引包含了查詢中WHERE子句和SELECT子句引用的所有列。這樣,當執(zhí)行查詢時,數據庫引擎就可以僅通過掃描索引來滿足查詢的需求,無需訪問表。

值得注意的是,雖然覆蓋索引可以提高查詢性能,但它也會增加數據庫的存儲空間和索引維護的開銷。因此,在設計和使用覆蓋索引時,需要權衡其帶來的性能提升和額外的存儲與維護成本。

總的來說,覆蓋索引是一種有效的優(yōu)化手段,可以在某些情況下顯著提高SQL查詢的性能。然而,它的使用需要根據具體的查詢和數據庫環(huán)境進行仔細的考慮和測試。

總的來說,%在LIKE語句中的位置對查詢性能有著重要影響。為了提高查詢性能,盡量避免在LIKE語句的開始處使用%通配符,而是盡量將通配符放在查詢模式的末尾或中間位置。同時,合理設計和使用索引也是提高查詢性能的關鍵。

所以,你知道為什么失效了么?

責任編輯:武曉燕 來源: Java極客技術
相關推薦

2020-12-11 08:02:16

索引MySQL存儲

2020-10-29 09:19:11

索引查詢存儲

2020-03-05 16:55:56

索引數據庫SQL

2020-11-27 06:58:24

索引

2011-01-18 15:27:30

Postfix

2020-09-16 06:51:37

Java線程JVM

2022-06-28 15:46:18

SQL語句索引

2020-08-10 11:20:59

索引MySQL數據庫

2022-04-13 20:53:15

Spring事務管理

2016-07-01 14:37:01

SparkSQL

2021-12-14 07:05:00

SQL語句數據庫

2018-06-26 15:58:06

數據庫MySQL索引優(yōu)化

2018-04-11 09:50:04

大數據

2018-04-02 10:58:28

大數據sqoop大數據項目

2020-01-22 16:36:52

MYSQL開源數據庫

2013-01-15 10:53:36

2013-01-16 14:29:22

2022-10-17 00:04:30

索引SQL訂單

2022-07-05 21:31:21

索引SQL分庫分表
點贊
收藏

51CTO技術棧公眾號