一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

MySQL 調優(yōu)技巧|索引什么時候失效?為什么?

 小生凡一 2024-12-15 發(fā)布于福建

寫在前面

優(yōu)化慢SQL,這是在工作或者面試中都不可避免的問題。這篇文章我們就來講講慢SQL的優(yōu)化的一些方法!

1. 升配

最簡單的一步就是升配!!當然在降本增效的當下,很難能將這種單子審批下來了!

2. 索引

MySQL一般會使用innodb作為存儲引擎,而innodb存儲引擎的索引結構為B+樹,索引有啥用?

mysql的數(shù)據(jù)是存儲在磁盤里的,而磁盤的io的隨機讀寫是很慢的,因為需要不斷的尋道,而索引是為了加速查詢的速度。

B+樹的結構如下:葉子結點存儲數(shù)值,非葉子結點存儲指針和鍵值。

在這里插入圖片描述

如果我們不加索引,MySQL就會進行全表掃描!如果加了索引,那么B+樹就會進行走索引!那么就會少走很多的磁盤io。

現(xiàn)在我們知道了為什么建索引,但并不是所有的字段都需要或者都需要建立索引的,因為索引也是占空間的,而且索引是有時候也會失效的! 也會影響到更新速度,這被稱為過度索引了,那么什么字段適合建立索引?什么字段不適合建立索引呢?

3. 什么字段適合建立索引?

大體可有以下四種情況:

  1. 針對查詢比較頻繁字段做索引,并且盡量選擇區(qū)分度高的列作為索引,盡量建立唯一索引,區(qū)分度越高,使用索引的效率越高。
  2. 盡量使用聯(lián)合索引,減少單列索引,查詢時,聯(lián)合索引很多時候可以索引覆蓋,避免回表,提高查詢效率。
  3. 索引應該建立在小字段上,對于大的文本字段不要建立索引。
  4. 要控制索引的數(shù)量,索引過多,維護索引結構的代價很大,會影響增刪改的效率

B+樹的本質是一顆平衡樹,當?shù)讓拥臄?shù)據(jù)量過大的時候,索引就會向上分裂,再合并,從而形成層。如果我們對性別這一類的字段建立索引,就會出現(xiàn)以下這種情況,這種情況其實和掃全表沒啥區(qū)別了,反而還浪費了空間。

在這里插入圖片描述
而如果是對一些重復度不高、唯一性很強的字段,比如用戶唯一id這種,建立索引,那么能很快速的找到這個數(shù)據(jù)。比如以下這種索引
在這里插入圖片描述

3. 什么時候索引會失效?為什么?

3.1 使用了不等號(<> 或 !=)

SELECT id,username FROM user WHERE age <> 18;

索引適合用于查找具體值或范圍值,如 =, <, >, BETWEEN 等操作,而 <> 或 != 運算符要求 MySQL 查找所有不等于某個值的記錄,范圍模糊且不能明確定位,索引不能高效定位這些記錄。`

3.2 OR 連接多個條件

SELECT id,username FROM user WHERE user_id = 1 OR age = 18;

當使用 OR 連接多個條件時,MySQL 可能無法有效地使用索引。為什么是可能?因為OR走索引與否,還和優(yōu)化器的預估有關,就算連接條件都設置了索引,也可能因為回表導致索引失效。

  • 索引 + OR + 無索引的列:會先走索引列,但無索引的列會進行全表掃描,所以還不如不走索引,直接都全表掃描完事。
  • 索引 + OR + 索引,那么可能走索引,也可能不走索引。

MySQL 會嘗試分別使用每個條件的索引,然后將結果合并,往往效率較低。解決方法其實很簡單,只需要將OR拆開,用UNION、UNION ALL拼接起來。

改成

SELECT id,username FROM user WHERE user_id = 1
UNION
SELECT id,username FROM user WHERE age = 18;

3.3 對索引列進行函數(shù)操作

當對索引列應用函數(shù)(如 UPPER(), YEAR(), CONCAT() 等),MySQL 不能直接在索引中查找優(yōu)化后的數(shù)據(jù),而是必須先計算函數(shù)結果,然后再去查找匹配的行。這會使得索引失效。

eg:

SELECT id,username FROM user WHERE YEAR(birthdate) = 2024;

在這里插入圖片描述
這里YEAR(birthdate) 是一個函數(shù),MySQL 不能直接利用 birthdate 列上的索引進行查詢,而需要先計算 YEAR(birthdate),導致索引失效。

3.4 隱式類型轉換

當查詢條件中的數(shù)據(jù)類型與表字段的數(shù)據(jù)類型不匹配時,MySQL 會進行隱式類型轉換。在這個過程中,可能導致索引失效,因為索引是基于特定的數(shù)據(jù)類型創(chuàng)建的,類型轉換后,可能無法高效利用索引。

eg:假設age是整數(shù)類型,但是卻使用字符串類型

SELECT * FROM user WHERE age = '20';

MySQL 需要在查詢時轉換 '20’ 為整數(shù)類型,可能會導致索引無法使用。 某個電商平臺就有這么一個類似的bug,導致下單超時崩盤30分鐘。

在這里插入圖片描述

3.5 范圍查詢與其他條件混合

如果一個復合索引包含多個列,并且查詢中有范圍條件,如 BETWEEN, >, <,MySQL 會優(yōu)先根據(jù)范圍條件來 定位數(shù)據(jù),而忽略其他條件。這種情況下,索引可能只會應用于范圍條件的列,其他列無法有效利用索引。

示例:

SELECT id,username FROM user WHERE birthdate > '2024-01-01' AND age = 18;

假設有一個復合索引 (birthdate, age),由于 birthdate > '2024-01-01’ 是一個范圍查詢,MySQL 只會使用 birthdate 列的索引,而 age 列則可能無法使用索引。

解決方法:盡量避免范圍查詢和精確查詢混合在同一個條件中,或者重新設計索引順序以適應查詢的特點。

eg:改成復合索引為 (age,birthdate) 并且SQL語句如下:

SELECT id,username FROM user WHERE age = 18 AND birthdate > '2024-01-01';

    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲熟女熟妇乱色一区| 正在播放玩弄漂亮少妇高潮| 欧美美女视频在线免费看| 天堂热东京热男人天堂| 日韩高清中文字幕亚洲| 在线免费国产一区二区| 91欧美亚洲精品在线观看| 久久偷拍视频免费观看| 黄片在线免费观看全集| 精品欧美日韩一二三区| 久久精品国产一区久久久| 精品日韩欧美一区久久| 黄男女激情一区二区三区| 久久精品亚洲精品一区| 一区二区三区日韩中文| 亚洲一区二区三区国产| 白丝美女被插入视频在线观看| 亚洲丁香婷婷久久一区| 亚洲高清中文字幕一区二区三区 | 亚洲精品熟女国产多毛| 老司机精品线观看86| 午夜成年人黄片免费观看| 高清一区二区三区四区五区| 中文字幕一区二区免费| 久久精品亚洲精品一区| 最近最新中文字幕免费| 欧美三级不卡在线观线看| 日韩国产亚洲欧美激情| 精品国产丝袜一区二区| 免费一级欧美大片免费看| 九九热九九热九九热九九热| 日本久久中文字幕免费| 亚洲五月婷婷中文字幕| 91精品国自产拍老熟女露脸 | 亚洲综合精品天堂夜夜| 久久免费精品拍拍一区二区| 日韩国产亚洲欧美激情| 日本中文字幕在线精品| 少妇高潮呻吟浪语91| 国产传媒高清视频在线| 欧美野外在线刺激在线观看|