最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL索引不生效的8種原因與解決方法

 更新時(shí)間:2025年09月25日 09:56:26   作者:師兄奇談  
在數(shù)據(jù)庫(kù)優(yōu)化中,最讓人頭疼的事情之一莫過(guò)于精心設(shè)計(jì)的索引沒(méi)有發(fā)揮作用,本文將整理8個(gè)MySQL索引不生效的原因與解決方法,需要的小伙伴可以了解下

在數(shù)據(jù)庫(kù)優(yōu)化中,最讓人頭疼的事情之一莫過(guò)于精心設(shè)計(jì)的索引沒(méi)有發(fā)揮作用。為什么會(huì)出現(xiàn)這種情況?

這篇文章帶大家一起探討一些常見(jiàn)原因,方便大家更好地理解MySQL查詢優(yōu)化器是如何選擇索引的,以及在出現(xiàn)類似問(wèn)題時(shí),可逐項(xiàng)進(jìn)行對(duì)照排查,

以一個(gè)簡(jiǎn)單的 people 表作為例子,表結(jié)構(gòu)如下:

CREATE TABLE `people` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  `first_name` varchar(50) NOT NULL,
  `last_name` varchar(50) NOT NULL,
  `state` char(2) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `first_name` (`first_name`),
  KEY `state` (`state`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

后續(xù)會(huì)以該表結(jié)構(gòu)為基礎(chǔ),通過(guò)添加或刪除索引來(lái)展示不同場(chǎng)景。

確認(rèn)索引是否被使用

在分析索引未生效的原因之前,首先需要判斷 MySQL 是否使用了索引。可以通過(guò) EXPLAIN 命令來(lái)查看查詢優(yōu)化器的分析結(jié)果,了解哪些索引被考慮,以及最終選擇使用了哪個(gè)索引。

例如,以下查詢會(huì)試圖通過(guò) first_name 索引查找數(shù)據(jù):

EXPLAIN SELECT * FROM people WHERE first_name = 'Aaron';

返回結(jié)果如下:

idtabletypepossible_keyskeykey_lenrefrowsfilteredExtra
1peoplereffirst_namefirst_name202const180100.00

從結(jié)果中可以看到:

  • possible_keys 表示查詢優(yōu)化器會(huì)考慮的索引,這里是 first_name 索引。
  • key 表示實(shí)際被選中的索引,也是 first_name。

關(guān)于EXPLAIN 的使用,可參考文末補(bǔ)充內(nèi)容

在本例中,first_name 索引不僅被優(yōu)化器考慮(considered),而且最終被選中(chosen)。這是兩個(gè)相關(guān)但不同的步驟:首先,優(yōu)化器會(huì)根據(jù)查詢篩選可用的索引;然后,選擇性能較優(yōu)的索引。

確認(rèn)索引是否被使用后,接下來(lái)分析一些索引未生效的常見(jiàn)原因。

索引未生效的原因

原因 1:另一個(gè)索引更優(yōu)

當(dāng)查詢可以利用多個(gè)索引時(shí),MySQL 優(yōu)化器會(huì)選擇其中最優(yōu)的索引。如果你的查詢可以同時(shí)使用多個(gè)索引,但最終未選擇預(yù)期的索引,很可能是因?yàn)榱硪粋€(gè)索引的效率更好。

例如,以下查詢同時(shí)使用 first_name 和 state 字段:

SELECT * FROM people
WHERE first_name = 'Aaron'
AND state = 'TX';

運(yùn)行 EXPLAIN 后結(jié)果如下:

idtabletypepossible_keyskeykey_lenrefrowsfilteredExtra
1peoplereffirst_name,statefirst_name202const18050.00Using where

在這個(gè)例子中,first_name 索引比 state 索引的選擇性更高,因此優(yōu)化器選擇了 first_name 索引。

原因 2:索引的選擇性和基數(shù)

索引的性能往往與選擇性和基數(shù)相關(guān):

  • 基數(shù)(Cardinality) 是列中不同值的數(shù)量。
  • 選擇性(Selectivity) 是指這些值的獨(dú)特程度(計(jì)算公式為 COUNT(DISTINCT column) / COUNT(*))。

比如,可以通過(guò)以下查詢計(jì)算基數(shù)和選擇性:

SELECT
  COUNT(DISTINCT first_name) as first_name_cardinality,
  COUNT(DISTINCT state) as state_cardinality,
  COUNT(DISTINCT first_name) / COUNT(*) as first_name_selectivity,
  COUNT(DISTINCT state) / COUNT(*) as state_selectivity
FROM people;

結(jié)果如下:

first_name_cardinalitystate_cardinalityfirst_name_selectivitystate_selectivity
300920.00600.0000
  • first_name 字段的不同值非常多,因此選擇性較高。
  • state 列選擇性極低,導(dǎo)致通過(guò) state 索引進(jìn)行過(guò)濾時(shí),效果較差。

高選擇性索引通常性能較優(yōu),而低選擇性索引在過(guò)濾數(shù)據(jù)時(shí)作用有限。

此外,唯一索引(如 id 的主鍵索引)通常具有完美選擇性。

原因 3:選擇性因查詢而異

索引的選擇性是基于整個(gè)表數(shù)據(jù)分布進(jìn)行計(jì)算的,但選擇性在具體查詢場(chǎng)景中可能不一樣。例如:

假如表中有 100 萬(wàn)行,其中 99% 的用戶類型是 user,只有 1% 為 admin,總體來(lái)看 type 列選擇性很低。但如果你的查詢條件是 type = 'admin',此時(shí)索引的作用就很明顯。

優(yōu)化器會(huì)根據(jù)查詢條件和數(shù)據(jù)分布動(dòng)態(tài)評(píng)估索引的價(jià)值。

原因 4:過(guò)時(shí)或不準(zhǔn)確的統(tǒng)計(jì)數(shù)據(jù)

MySQL 的索引基數(shù)統(tǒng)計(jì)信息是通過(guò)隨機(jī)采樣維護(hù)的,可能出現(xiàn)因統(tǒng)計(jì)信息過(guò)時(shí)而導(dǎo)致優(yōu)化器做出錯(cuò)誤決策的情況。可以通過(guò)以下命令更新統(tǒng)計(jì)信息:

ANALYZE TABLE people;

如果統(tǒng)計(jì)數(shù)據(jù)采樣精度不足,可以通過(guò)調(diào)整 MySQL 的相關(guān)參數(shù)改善采樣質(zhì)量。

原因 5:表掃描更快

某些情況下,優(yōu)化器會(huì)選擇直接掃描整個(gè)表而不是使用索引。這可能發(fā)生在以下場(chǎng)景:

  • 表的大小較小,表掃描成本幾乎可以忽略。
  • 查詢需要獲取大部分表數(shù)據(jù),索引的過(guò)濾能力不足,導(dǎo)致索引的額外開(kāi)銷反而拖慢查詢速度。

雖然表掃描看起來(lái)反直覺(jué),但在特定情況下確實(shí)更高效。

原因 6:索引的結(jié)構(gòu)性限制

理解索引的底層結(jié)構(gòu)(如 B+ 樹(shù)),有助于分析某些查詢?yōu)槭裁礋o(wú)法用到索引。主要有以下幾個(gè)場(chǎng)景:

場(chǎng)景 1:通配符搜索

MySQL 的索引只能用于匹配字符串的前綴部分,不能用于字符串中的后綴或包含部分。例如:

  • 查詢 LIKE 'Aa%' 可以使用索引。
  • 查詢 LIKE '%ron' 則無(wú)法使用索引。

如果你需要復(fù)雜的字符串搜索,可以考慮使用全文索引(Fulltext Index)或?qū)iT(mén)設(shè)計(jì)的數(shù)據(jù)模型。

場(chǎng)景 2:復(fù)合索引的左前綴規(guī)則

復(fù)合索引要求使用時(shí)遵循“左前綴”規(guī)則,例如:

ALTER TABLE people ADD INDEX multi (first_name, state);
  • 查詢條件包含 first_name 和 state 時(shí)會(huì)正確使用索引。
  • 查詢條件僅包含 state 時(shí)因不滿足左前綴無(wú)法使用復(fù)合索引。

場(chǎng)景 3:連接列類型或字符集不匹配

若連接的字段類型或字符集不一致,索引將無(wú)法生效。例如:

  • VARCHAR(10) 和 CHAR(10) 類型和長(zhǎng)度相同,索引可用。
  • VARCHAR(10) 和 CHAR(15) 則因長(zhǎng)度不同導(dǎo)致索引不可用。

確保字段定義一致是索引生效的前提。

原因 7:索引被模糊化處理

某些查詢因?qū)ψ侄问褂昧撕瘮?shù)或運(yùn)算導(dǎo)致索引無(wú)法使用。例如:

SELECT * FROM people WHERE YEAR(created_at) = 2023;

上述查詢無(wú)法使用 created_at 索引,因?yàn)?MySQL 沒(méi)法直接基于函數(shù)計(jì)算進(jìn)行優(yōu)化。替代方案如下:

SELECT * FROM people WHERE created_at BETWEEN '2023-01-01' AND '2023-12-31';

通過(guò)范圍查詢可以正常使用索引。

原因 8:隱藏索引

MySQL 支持隱藏索引,隱藏索引不會(huì)被查詢優(yōu)化器使用。例如:

ALTER TABLE people ALTER INDEX first_name INVISIBLE;

Hidden 索引可以用于測(cè)試索引刪除的影響,若查詢性能下降可以隨時(shí)恢復(fù)索引。

強(qiáng)制使用索引

如果你認(rèn)為 MySQL 優(yōu)化器的決策不正確,可以通過(guò) USE INDEX 提示優(yōu)化器使用指定索引:

EXPLAIN SELECT * FROM people USE INDEX (state) WHERE first_name = 'Aaron' AND state = 'TX';

但使用 USE INDEX 應(yīng)該謹(jǐn)慎,因?yàn)榭赡茉跀?shù)據(jù)量增長(zhǎng)后需要重新評(píng)估是否強(qiáng)制使用某索引。

知識(shí)補(bǔ)充

僅僅會(huì)用MySQL的EXPLAIN還不夠,還需要會(huì)用EXPLAIN ANALYZE

在 MySQL 中,EXPLAIN 是一個(gè)關(guān)鍵字,用于了解查詢執(zhí)行的相關(guān)信息。本文將展示如何利用MySQL EXPLAIN 來(lái)解決查詢中的性能問(wèn)題。

雖然執(zhí)行一個(gè) EXPLAIN 計(jì)劃相對(duì)簡(jiǎn)單,但其輸出結(jié)果并不總是直觀的。只有了解其功能,才能充分利用它來(lái)實(shí)現(xiàn)SQL語(yǔ)句的性能提升。

EXPLAIN 與 EXPLAIN ANALYZE 的區(qū)別

當(dāng)在查詢的前面添加 EXPLAIN 關(guān)鍵字時(shí),它會(huì)解釋數(shù)據(jù)庫(kù)如何執(zhí)行該查詢以及估算的成本。

示例EXPLAIN語(yǔ)句:

通過(guò)利用這個(gè)MySQL 內(nèi)部工具,可以觀察到以下內(nèi)容:

  • 查詢 ID:列中總包含一個(gè)數(shù)值,用于標(biāo)識(shí)該行屬于哪一個(gè) SELECT。
  • SELECT_TYPE:運(yùn)行 SELECT 時(shí),MySQL 將 SELECT 查詢分為簡(jiǎn)單類型和復(fù)雜類型(主要),如下表所示:
    • SIMPLE:查詢不包含子查詢或 UNION;
    • PRIMARY(復(fù)雜類型):復(fù)雜類型分為三大類:簡(jiǎn)單子查詢、派生表(FROM 子句中的子查詢)、UNION;
    • DELETE:如果EXPLAIN的是 DELETE,select_type 會(huì)顯示 DELETE;
  • 查詢運(yùn)行的表 :顯示執(zhí)行計(jì)劃中每一步驟所涉及的表。
  • 查詢?cè)L問(wèn)的分區(qū) :列出訪問(wèn)了哪些表分區(qū)(如果表已分區(qū))。
  • 所使用的連接類型(如果有):請(qǐng)注意,即使查詢中不包含連接,這一列也會(huì)填充。
  • MySQL 可以選擇的索引 :列出所有可能的候選索引。
  • MySQL 實(shí)際使用的索引 :顯示查詢選擇的索引,并指定索引的使用長(zhǎng)度。
  • MySQL 選擇的索引的長(zhǎng)度:當(dāng) MySQL 使用復(fù)合索引時(shí),length 列是唯一能確定復(fù)合索引中的使用了多少列的方法。
  • 查詢?cè)L問(wèn)的行數(shù):在設(shè)計(jì)數(shù)據(jù)庫(kù)實(shí)例中的索引時(shí),需要注意 rows 列。該列顯示了 MySQL 為完成請(qǐng)求而訪問(wèn)的行數(shù),這在設(shè)計(jì)索引時(shí)非常實(shí)用。查詢?cè)L問(wèn)的行越少,查詢速度越快。
  • 與索引進(jìn)行比較的列
  • 按指定條件過(guò)濾的行的百分比:該列顯示了滿足表上某些條件(如 WHERE 子句或連接條件)的行的悲觀估算百分比。將 rows 列的值乘以該百分比,可以看到 MySQL 估計(jì)要與查詢計(jì)劃中先前的表連接的行數(shù)。
  • 與查詢相關(guān)的任何額外信息

總之,通過(guò)使用 EXPLAIN,可以獲得查詢預(yù)期運(yùn)行的步驟列表。

什么是 EXPLAIN ANALYZE

在 MySQL 8.0.18 中,MySQL 引入了 EXPLAIN ANALYZE,一個(gè)在常規(guī) EXPLAIN 查詢計(jì)劃工具之上的新功能。除了列出查詢計(jì)劃和估算的成本,EXPLAIN ANALYZE 還打印了執(zhí)行計(jì)劃中各個(gè)迭代器的實(shí)際成本。

示例EXPLAIN ANALYZE語(yǔ)句:

注意事項(xiàng):EXPLAIN ANALYZE 實(shí)際上會(huì)運(yùn)行查詢,因此如果你不希望查詢?cè)趯?shí)時(shí)數(shù)據(jù)庫(kù)上運(yùn)行,請(qǐng)不要使用 EXPLAIN ANALYZE。

對(duì)于每個(gè)迭代器,EXPLAIN ANALYZE 提供以下信息:

  • 估算的執(zhí)行成本(一些迭代器未被成本模型納入,因此在估算中未包含它們)
  • 估算的返回行數(shù)
  • 返回第一行所需的時(shí)間
  • 執(zhí)行迭代器所花費(fèi)的時(shí)間(包括子迭代器但不包括父迭代器),單位:毫秒。當(dāng)有多個(gè)循環(huán)時(shí),該數(shù)據(jù)會(huì)顯示平均每個(gè)循環(huán)所需的時(shí)間。
  • 迭代器返回的行數(shù)
  • 循環(huán)的次數(shù)

MySQL EXPLAIN ANALYZE 的結(jié)果會(huì)顯示查詢運(yùn)行前規(guī)劃器的估算數(shù)據(jù)(如圖中黃色突出顯示部分)和查詢實(shí)際運(yùn)行后的數(shù)據(jù)(如綠色突出顯示部分)。

EXPLAIN ANALYZE 的格式

EXPLAIN ANALYZE 可用于 SELECT 語(yǔ)句、多表 UPDATE 語(yǔ)句、DELETE 語(yǔ)句和 TABLE 語(yǔ)句。它會(huì)自動(dòng)選擇 FORMAT=tree 并執(zhí)行查詢(不會(huì)向用戶顯示任何輸出)。EXPLAIN ANALYZE 專注于查詢執(zhí)行的關(guān)系以及部分查詢的執(zhí)行順序。

EXPLAIN 輸出以節(jié)點(diǎn)形式組織。在最低層,節(jié)點(diǎn)會(huì)掃描表或搜索索引;較高層的節(jié)點(diǎn)則操作來(lái)自低層節(jié)點(diǎn)的結(jié)果。

雖然 MySQL CLI 能以表格、制表符、垂直格式,以及漂亮或原始 JSON 格式打印 EXPLAIN 結(jié)果,但目前 EXPLAIN ANALYZE 不支持 JSON 格式。

EXPLAIN 和EXPLAIN ANALYZE的使用場(chǎng)景

當(dāng)你不確定查詢是否高效運(yùn)行時(shí),可以(且應(yīng))使用 EXPLAIN 查詢。如果你認(rèn)為已經(jīng)正確索引并分區(qū)了表,但查詢依舊運(yùn)行緩慢,則可能需要使用EXPLAIN ANALYZE了。當(dāng)查詢進(jìn)行EXPLAIN ANALYZE之后,就需要關(guān)注的輸出內(nèi)容以及優(yōu)化目標(biāo)了。

1.索引相關(guān)列:keys、possible keys 和 key lengths

在 MySQL 中處理索引時(shí),需關(guān)注 possible_keys、key 和 key_len 列。

  • possible_keys 列顯示了 MySQL 可以選擇的索引。
  • key 列顯示了實(shí)際選擇的索引。
  • key_len 列顯示了所選索引的長(zhǎng)度。

這些信息對(duì)設(shè)計(jì)索引、為特定任務(wù)決定使用何種索引,以及處理相關(guān)問(wèn)題(如選擇覆蓋索引的適當(dāng)長(zhǎng)度)非常實(shí)用。

2.FULLTEXT 索引與連接

當(dāng)使用 FULLTEXT 索引確保查詢參與 JOIN 操作時(shí),需注意 select_type 列,該列的值應(yīng)為 fulltext。

3.分區(qū)

如果表已添加分區(qū)并希望查詢使用這些分區(qū),要觀察 partition 列。如果 MySQL 實(shí)例正在使用分區(qū),在大多數(shù)情況下,MySQL 會(huì)自動(dòng)處理所有查詢,而無(wú)需額外操作。如果希望查詢使用特定分區(qū),可以使用類似 SELECT * FROM TABLE_NAME PARTITION(p1,p2) 的查詢。

EXPLAIN 的局限性

EXPLAIN 是一種估算工具。它有時(shí)是一個(gè)比較準(zhǔn)確的估算,但有時(shí)可能非常不精確。以下是一些局限性:

  • EXPLAIN 不會(huì)告訴你觸發(fā)器、存儲(chǔ)函數(shù)或 UDF 對(duì)查詢的影響。
  • 它不能分析存儲(chǔ)過(guò)程。
  • 它不會(huì)展示 MySQL 在查詢執(zhí)行期間的優(yōu)化過(guò)程。
  • 一些統(tǒng)計(jì)數(shù)據(jù)是估算值,可能非常不準(zhǔn)確。
  • 它不會(huì)區(qū)分某些具有相同名稱的內(nèi)容。例如,它用 filesort 表示內(nèi)存排序和磁盤(pán)排序,用 Using temporary 表示內(nèi)存臨時(shí)表和磁盤(pán)臨時(shí)表。

SHOW WARNINGS 語(yǔ)句

需要注意的一點(diǎn)是:如果你用 EXPLAIN 的查詢未正確解析,可以輸入 SHOW WARNINGS; 查看最后一個(gè)運(yùn)行的非診斷語(yǔ)句的信息。雖然它無(wú)法提供像 EXPLAIN 那樣的查詢執(zhí)行計(jì)劃,但它可能提供關(guān)于可處理的查詢片段的線索。

SHOW WARNINGS; 包含一些特殊標(biāo)記,其中信息可能包括:

  • <index_lookup>(query fragment):表明如果查詢正確解析會(huì)進(jìn)行索引查找。
  • <if>(condition, expr1, expr2):表明該查詢特定部分有 IF 條件。
  • <primary_index_lookup>(query fragment):表明通過(guò)主鍵進(jìn)行索引查找。
  • <temporary table>:表明這里會(huì)創(chuàng)建內(nèi)部表以保存臨時(shí)結(jié)果(例如在連接之前的子查詢中)。

MySQL EXPLAIN 的連接類型

MySQL 手冊(cè)提到 type 列顯示“連接類型”,用以解釋表的連接方式。但實(shí)際上更準(zhǔn)確的說(shuō)法是“訪問(wèn)類型”,即告訴我們 MySQL 決定如何在表中找到行。

以下列出從性能最佳到最差的重要訪問(wèn)方式:

  • NULL(較好):表示 MySQL 在優(yōu)化階段即可解析查詢,不會(huì)在執(zhí)行階段訪問(wèn)表或索引。
  • system(較好):表為空或僅有一行記錄。
  • const(較好):列值可視為常量(即查詢只匹配一行)。注:主鍵查找、唯一索引查找。
  • eq_ref(較好):索引是聚簇索引,被 操作使用(索引為主鍵或 NOT NULL 的唯一索引)。
  • ref(較好):使用等值運(yùn)算符訪問(wèn)索引列。注:ref_or_nullref 的變種,表示初次查找后需再查找 NULL 條目。
  • fulltext(一般):操作(JOIN)使用了表的 FULLTEXT 索引。
  • index(一般):掃描整個(gè)索引以找到查詢匹配項(xiàng)。注:主要優(yōu)勢(shì)是無(wú)需排序;主要劣勢(shì)是讀取整張表成本高。
  • range(一般):范圍掃描為受限索引掃描,從索引某點(diǎn)開(kāi)始返回匹配范圍內(nèi)的記錄。注:這比全索引掃描更優(yōu)。
  • all(一般):MySQL 為滿足查詢而掃描全表。

還有一些其他類型需要了解:

  • index_merge:此連接類型表示使用了索引合并優(yōu)化,即通過(guò)多索引聯(lián)合查詢單表。
  • unique_subquery:此類型替代某些形式的 eq_ref。通常用于以下形式的子查詢:value IN (SELECT primary_key FROM single_table WHERE some_expr)。
  • index_subquery:與 unique_subquery 類似,但應(yīng)用于非唯一索引的子查詢。

EXPLAIN 的 EXTRA 列

EXTRA 列包含其他列中未涵蓋的額外信息。以下是一些重要值及其定義:

  • Using index:表示 MySQL 將使用覆蓋索引避免訪問(wèn)表。
  • Using where:MySQL 服務(wù)器將在存儲(chǔ)引擎檢索行后進(jìn)行行的后過(guò)濾。
  • Using temporary:MySQL 會(huì)通過(guò)臨時(shí)表保存排序結(jié)果。
  • Using filesort:MySQL 使用外部排序來(lái)排序結(jié)果而非按照索引順序讀取行。
  • Range checked for each record:(index map:N),表示沒(méi)有合適索引,并會(huì)對(duì)連接中的每行重新評(píng)估索引。
  • Using index condition:表通過(guò)訪問(wèn)索引元組并在讀取完整表之前進(jìn)行測(cè)試讀取。
  • Backward index scan:MySQL 使用降序索引完成查詢。
  • const row not found:表明查詢的表為空。
  • Using index for group-by:表明 MySQL 能利用某個(gè)索引優(yōu)化 GROUP BY 操作。

EXPLAIN 優(yōu)化查詢的實(shí)踐示例

下面通過(guò)一個(gè)實(shí)踐案例來(lái)演示一下使用 MySQL EXPLAIN 優(yōu)化查詢的方法。

1.運(yùn)行初始查詢

在開(kāi)始之前,先創(chuàng)建一個(gè)數(shù)據(jù)庫(kù),并使用MySQL員工樣例數(shù)據(jù)庫(kù)進(jìn)行初始化。

通過(guò)使用多列索引和MySQL EXPLAIN,允許數(shù)據(jù)庫(kù)引擎聯(lián)合使用多列加速查詢。

例如,優(yōu)化下列查詢:

SELECT * FROM employees WHERE last_name = 'Puppo' AND first_name = 'Kendra';

在運(yùn)行該查詢后,EXPLAIN 的結(jié)果顯示訪問(wèn)了 299,733 行,而這是我們需要優(yōu)化以提升性能的根本原因。

優(yōu)化方法 1:創(chuàng)建兩個(gè)獨(dú)立索引

一種方法是分別為 last_name 列和 first_name 列創(chuàng)建單獨(dú)索引,但這種方式有一個(gè)問(wèn)題——MySQL 知道如何找到所有姓 Puppo 的員工,也知道如何找到所有名為 Kendra 的員工,但卻無(wú)法同時(shí)高效找到名為 Kendra Puppo 的員工。

其他需要注意的事項(xiàng):

  • 當(dāng)面對(duì)多個(gè)不相關(guān)的索引以及包含多個(gè)過(guò)濾條件的查詢時(shí),MySQL 有幾種選擇可以用來(lái)處理這些情況。
  • MySQL 支持索引合并優(yōu)化(Index Merge),可聯(lián)合使用多個(gè)索引來(lái)執(zhí)行查詢。然而,這種優(yōu)化有一定局限性,因此在構(gòu)建索引時(shí)應(yīng)該將其視為一般規(guī)則。MySQL 可能會(huì)決定不使用多個(gè)索引;即使會(huì)使用,在很多情況下,多個(gè)索引的聯(lián)合效果也遠(yuǎn)遠(yuǎn)不如一個(gè)專門(mén)的索引。

優(yōu)化方法 2:使用多列索引

由于第一種方法的問(wèn)題,我們知道需要找到一種解決方案來(lái)使用能夠考慮多列的索引。這里我們可以使用多列索引來(lái)實(shí)現(xiàn)這一目標(biāo)。

可以將其想象成一本電話簿嵌套在另一本電話簿中。首先,查閱姓氏 “Puppo”,然后進(jìn)入第二個(gè)目錄,該目錄按名字的字母順序組織所有名為 “Kendra” 的人,在這個(gè)目錄中可以快速找到“Kendra Puppo”。

在 MySQL 中,若要為 employees 表中的姓氏和名字創(chuàng)建多列索引,可以執(zhí)行以下命令:

CREATE INDEX fullnames ON employees(last_name, first_name);

現(xiàn)在,多列索引已成功創(chuàng)建,我們可以執(zhí)行以下 SELECT 查詢來(lái)查找名字為 Kendra 且姓氏為 Puppo 的記錄。結(jié)果將是一行數(shù)據(jù),其中包含名為 Kendra Puppo 的員工信息。

使用 EXPLAIN 來(lái)檢查該查詢是否使用了索引:

查詢優(yōu)化后的結(jié)果顯示,索引被使用,并且只訪問(wèn)了一行數(shù)據(jù)來(lái)完成請(qǐng)求。這比優(yōu)化前必須訪問(wèn) 299,733 行要高效得多。

總結(jié)

索引優(yōu)化涉及多個(gè)方面,包括查詢優(yōu)化器運(yùn)作、數(shù)據(jù)分布、索引結(jié)構(gòu)等。了解索引未生效的原因并合理優(yōu)化查詢,可以顯著提升數(shù)據(jù)庫(kù)性能。索引雖強(qiáng)大,但只有正確規(guī)劃和使用才能發(fā)揮最大效用。

到此這篇關(guān)于MySQL索引不生效的8種原因與解決方法的文章就介紹到這了,更多相關(guān)MySQL索引不生效內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL系列之四 SQL語(yǔ)法

    MySQL系列之四 SQL語(yǔ)法

    SQL是一種特殊目的的編程語(yǔ)言,是一種數(shù)據(jù)庫(kù)查詢和程序設(shè)計(jì)語(yǔ)言,用于存取數(shù)據(jù)以及查詢、更新和管理關(guān)系數(shù)據(jù)庫(kù)系統(tǒng),這篇文章主要給大家介紹了SQL語(yǔ)法的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • MySQL中FIND_IN_SET(),IN( )和?LIKE區(qū)別小結(jié)

    MySQL中FIND_IN_SET(),IN( )和?LIKE區(qū)別小結(jié)

    在MySQL中,FIND_IN_SET()、LIKE和IN用于字符串和值的匹配查找,FIND_IN_SET()適用于逗號(hào)分隔的字符串列表,LIKE用于模糊匹配,IN用于離散值列表,下面就來(lái)介紹了一下具體的區(qū)別,感興趣的可以了解一下
    2026-02-02
  • MySQL中JSON數(shù)據(jù)存儲(chǔ)的最佳實(shí)踐指南(直接存儲(chǔ) vs 文件路徑存儲(chǔ))

    MySQL中JSON數(shù)據(jù)存儲(chǔ)的最佳實(shí)踐指南(直接存儲(chǔ) vs 文件路徑存儲(chǔ))

    文章對(duì)比了直接存儲(chǔ)JSON到MySQL字段和存儲(chǔ)JSON文件路徑兩種方案,分析了各自的優(yōu)缺點(diǎn),并提供了基于MySQL的實(shí)現(xiàn)建議,最終建議根據(jù)具體業(yè)務(wù)需求選擇合適的方案,感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • MySQL主從延遲全鏈路根因診斷與解決方法

    MySQL主從延遲全鏈路根因診斷與解決方法

    本文介紹了MySQL主從復(fù)制延遲的診斷與優(yōu)化方法,從復(fù)制原理出發(fā),分析了主從延遲的四大根因:硬件資源不對(duì)等、大事務(wù)與長(zhǎng)事務(wù)、鎖沖突和網(wǎng)絡(luò)抖動(dòng),并提供了詳細(xì)的診斷步驟和優(yōu)化建議,包括開(kāi)啟并行復(fù)制、治理大事務(wù)和DDL操作、緩存解耦等,需要的朋友可以參考下
    2026-04-04
  • MySQL根據(jù) ID 將表 B 的字段更新到表 A的實(shí)戰(zhàn)教程

    MySQL根據(jù) ID 將表 B 的字段更新到表 A的實(shí)戰(zhàn)教程

    這篇文章主要介紹了MySQL根據(jù) ID 將表 B 的字段更新到表 A的實(shí)戰(zhàn)教程,本文將系統(tǒng)梳理幾種常見(jiàn)寫(xiě)法,并分析它們的優(yōu)缺點(diǎn),需要的朋友可以參考下
    2026-04-04
  • 2023最新安裝mysql8.0.33方式教程

    2023最新安裝mysql8.0.33方式教程

    這幾天被各種環(huán)境的配置搞瘋了,查詢了很多資料,也算有點(diǎn)經(jīng)驗(yàn),對(duì)于Mysql的安裝進(jìn)行了總結(jié),這篇文章主要給大家介紹了關(guān)于2023年最新安裝mysql8.0.33的方式教程,需要的朋友可以參考下
    2023-06-06
  • MySQL 基礎(chǔ)常用命令總結(jié)

    MySQL 基礎(chǔ)常用命令總結(jié)

    這篇文章主要介紹了MySQL 的基礎(chǔ)常用命令,在執(zhí)行語(yǔ)句的時(shí)候,很多命令都是必須記住的,想具體了解的小伙伴請(qǐng)參考下面文章內(nèi)容
    2021-09-09
  • MySQL中列子查詢與行子查詢操作的學(xué)習(xí)教程

    MySQL中列子查詢與行子查詢操作的學(xué)習(xí)教程

    這篇文章主要介紹了MySQL中列子查詢與行子查詢操作的學(xué)習(xí)教程,子查詢是MySQL入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-12-12
  • mysql5.7.20第一次登錄失敗的快速解決方法

    mysql5.7.20第一次登錄失敗的快速解決方法

    這篇文章主要介紹了mysql5.7.20第一次登錄失敗的快速解決方法,需要的朋友可以參考下
    2018-09-09
  • MySQL中CHAR和VARCHAR類型的區(qū)別及說(shuō)明

    MySQL中CHAR和VARCHAR類型的區(qū)別及說(shuō)明

    這篇文章主要介紹了MySQL中CHAR和VARCHAR類型的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-08-08

最新評(píng)論

山东| 祥云县| 小金县| 沁水县| 武城县| 宽甸| 台南市| 瑞昌市| 肇庆市| 和田县| 陕西省| 兴义市| 察雅县| 广州市| 洛隆县| 万州区| 会昌县| 新河县| 突泉县| 紫阳县| 科技| 湖南省| 汝城县| 张家港市| 乌拉特中旗| 大理市| 昭通市| 富顺县| 三河市| 礼泉县| 张家港市| 大关县| 繁昌县| 邯郸市| 桑植县| 伊宁县| 福建省| 灌阳县| 镇康县| 木兰县| 炉霍县|