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

MySQL聯(lián)合索引設(shè)計(jì)中字段順序、區(qū)分度與優(yōu)化器行為示例詳解

 更新時(shí)間:2025年11月13日 11:05:31   作者:代碼怪獸大大作戰(zhàn)  
索引設(shè)計(jì)是數(shù)據(jù)庫(kù)優(yōu)化中的關(guān)鍵環(huán)節(jié),遵循三大黃金原則可顯著提升查詢性能,這篇文章主要介紹了MySQL聯(lián)合索引設(shè)計(jì)中字段順序、區(qū)分度與優(yōu)化器行為的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下,

在日常開(kāi)發(fā)中,我們常常為查詢加上聯(lián)合索引,例如:

CREATE INDEX idx_unit_user ON t_user (unit_id, user_id);

但在很多項(xiàng)目里,還能看到這種寫法:

CREATE INDEX idx_del_unit_user ON t_user (del_flag, unit_id, user_id);

del_flag 表示是否刪除,只有 01 兩種取值。

很多人認(rèn)為“查詢總有 del_flag=0 條件,索引當(dāng)然要從它開(kāi)始”,

但事實(shí)上,這樣反而可能拖慢查詢速度。

本文將系統(tǒng)講清楚三個(gè)關(guān)鍵問(wèn)題

  1. 聯(lián)合索引字段順序的重要性

  2. 區(qū)分度(Cardinality)對(duì)索引效率的影響

  3. MySQL 優(yōu)化器是否會(huì)自動(dòng)調(diào)整 WHERE 條件順序

一、聯(lián)合索引的匹配原理回顧

聯(lián)合索引 (a, b, c) 的底層是一個(gè) B+Tree。

MySQL 檢索時(shí)會(huì)按照索引定義的列順序有序排列:

a → b → c

因此,它遵循 最左前綴原則(Leftmost Prefix Rule)

  • 可以命中 (a)、(a,b)、(a,b,c);

  • 但無(wú)法單獨(dú)命中 (b)(c)(b,c)。

這意味著:索引列的順序決定了 MySQL 能否利用該索引。

二、區(qū)分度(Cardinality)是什么?

區(qū)分度是衡量字段“區(qū)分能力”的指標(biāo):

區(qū)分度 = 不同值數(shù)量 / 總記錄數(shù)

可通過(guò)命令查看:

SHOW INDEX FROM your_table;

其中 Cardinality 表示索引中不同值的大致數(shù)量。

字段取值示例區(qū)分度是否適合放在索引前面
del_flag0/1極低?
genderM/F極低?
unit_id上千單位中高?
user_id唯一極高?

三、為什么低區(qū)分度字段放前面會(huì)拖慢查詢?

假設(shè)你定義了:

CREATE INDEX idx_del_unit_user ON t_user (del_flag, unit_id, user_id);

del_flag 只有兩種值(0、1)。

查詢?nèi)缦拢?/p>

SELECT * FROM t_user WHERE del_flag = 0 AND unit_id = 1001;

索引的邏輯結(jié)構(gòu)類似:

(del_flag=0) → [unit_id 排序 ...]

(del_flag=1) → [unit_id 排序 ...]

MySQL 實(shí)際上會(huì)掃描整個(gè) (del_flag=0) 這半邊索引樹(shù),

再在其中過(guò)濾出 unit_id=1001 的數(shù)據(jù)。

因?yàn)?del_flag 不能有效縮小數(shù)據(jù)范圍,性能幾乎無(wú)提升。

低區(qū)分度列放在前面時(shí),索引分區(qū)極不均衡,效果有限。

四、優(yōu)化設(shè)計(jì):高區(qū)分度字段放前

如果查詢模式是:

WHERE del_flag=0 AND unit_id=? AND user_id=?

更合理的索引應(yīng)為:

CREATE INDEX idx_unit_user_del ON t_user (unit_id, user_id, del_flag);

執(zhí)行順序如下:

  1. MySQL 先根據(jù) unit_id 定位;

  2. 再通過(guò) user_id 精確匹配;

  3. 最后判斷 del_flag=0。

結(jié)果是:掃描范圍更小,性能顯著提升。

五、WHERE 條件順序會(huì)影響嗎?

很多人問(wèn):

“如果我寫的 SQL 是 WHERE del_flag=0 AND unit_id=? AND user_id=?,
那是不是應(yīng)該把 unit_id 放前面?”

答案是:不用。

MySQL 優(yōu)化器會(huì)自動(dòng)調(diào)整邏輯順序

MySQL 的優(yōu)化器會(huì):

  • 自動(dòng)重排 WHERE 條件;

  • 根據(jù)各條件的“選擇性”(區(qū)分度)判斷最優(yōu)的索引路徑;

  • 但它不會(huì)改變索引的定義順序。

換句話說(shuō):

  • 寫 SQL 的順序不重要

  • 索引定義的順序才重要。

實(shí)測(cè)驗(yàn)證

索引:

CREATE INDEX idx_unit_user_del ON t_user (unit_id, user_id, del_flag);

兩條 SQL:

EXPLAIN SELECT * FROM t_user 
WHERE del_flag=0 AND unit_id=1001 AND user_id=8888;

EXPLAIN SELECT * FROM t_user 
WHERE unit_id=1001 AND user_id=8888 AND del_flag=0;

結(jié)果完全一致:

key: idx_unit_user_del
key_len: ...
rows: 1
Extra: Using index condition

? 說(shuō)明優(yōu)化器自動(dòng)識(shí)別了最優(yōu)執(zhí)行路徑,
WHERE 條件順序無(wú)關(guān)緊要。

但優(yōu)化器不會(huì)“反轉(zhuǎn)索引”

如果索引定義是:

CREATE INDEX idx_del_unit_user ON t_user (del_flag, unit_id, user_id);

那無(wú)論你寫:

WHERE unit_id=1001 AND user_id=8888 AND del_flag=0;

還是反過(guò)來(lái)寫,

優(yōu)化器都無(wú)法跳過(guò) del_flag 直接用 (unit_id, user_id)。

只能從 del_flag=0 那個(gè)分支掃描,性能依然很差。

六、實(shí)戰(zhàn)對(duì)比

查詢索引是否命中說(shuō)明
WHERE unit_id=? AND user_id=? AND del_flag=0(unit_id, user_id, del_flag)? 完整命中?? 性能最優(yōu)
WHERE del_flag=0 AND unit_id=? AND user_id=?(unit_id, user_id, del_flag)? 完整命中?? 一樣快
WHERE del_flag=0 AND unit_id=?(unit_id, user_id, del_flag)? 部分命中?? 仍快
WHERE del_flag=0(unit_id, user_id, del_flag)? 不命中最左前綴?? 慢
WHERE unit_id=? AND user_id=?(del_flag, unit_id, user_id)? 無(wú)法跳過(guò) del_flag?? 慢

七、區(qū)分度與索引順序的設(shè)計(jì)原則

原則說(shuō)明
區(qū)分度優(yōu)先高區(qū)分度列放在前(如 unit_id、user_id)
過(guò)濾性優(yōu)先查詢中最能減少掃描范圍的條件放前
穩(wěn)定性優(yōu)先每次查詢必帶的條件(如 del_flag)放最后
低區(qū)分度列不單獨(dú)建索引例如 0/1、狀態(tài)、布爾值
用 EXPLAIN 驗(yàn)證執(zhí)行計(jì)劃理論與實(shí)際可能受統(tǒng)計(jì)信息影響

八、推薦實(shí)踐模板

查詢場(chǎng)景推薦索引
WHERE del_flag=0 AND unit_id=?(unit_id, del_flag)
WHERE del_flag=0 AND user_id=?(user_id, del_flag)
WHERE del_flag=0 AND unit_id=? AND user_id=?(unit_id, user_id, del_flag)

?? 不推薦 (del_flag, unit_id, user_id)
? 推薦 (unit_id, user_id, del_flag)

九、總結(jié)

重點(diǎn)說(shuō)明
? 索引順序決定可用性最左前綴原則
? 區(qū)分度決定效率區(qū)分度高 → 放前面
? WHERE 條件順序無(wú)關(guān)緊要優(yōu)化器會(huì)自動(dòng)重排
? 低區(qū)分度列放前浪費(fèi)索引如 del_flag、status
? 正確索引能提升數(shù)十倍性能用 EXPLAIN 驗(yàn)證

?? 一句話總結(jié):

MySQL 會(huì)自動(dòng)優(yōu)化 WHERE 條件順序,但不會(huì)改變索引定義順序。
因此,請(qǐng)始終把高區(qū)分度字段放在聯(lián)合索引前列,
把低區(qū)分度的 del_flag、status 等放在最后。

到此這篇關(guān)于MySQL聯(lián)合索引設(shè)計(jì)中字段順序、區(qū)分度與優(yōu)化器行為的文章就介紹到這了,更多相關(guān)MySQL聯(lián)合索引字段順序、區(qū)分度與優(yōu)化器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL數(shù)字類型自增的坑

    MySQL數(shù)字類型自增的坑

    這篇文章主要介紹了MySQL數(shù)字類型自增的坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 一文解決連接MySQL報(bào)錯(cuò)is?not?allowed?to?connect?to?this?MySQL?server

    一文解決連接MySQL報(bào)錯(cuò)is?not?allowed?to?connect?to?this?MySQL?

    這篇文章主要給大家介紹了關(guān)于如何通過(guò)一文解決連接MySQL報(bào)錯(cuò)is?not?allowed?to?connect?to?this?MySQL?server的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-08-08
  • mysql大小寫敏感導(dǎo)致程序無(wú)法啟動(dòng)的問(wèn)題

    mysql大小寫敏感導(dǎo)致程序無(wú)法啟動(dòng)的問(wèn)題

    這篇文章主要介紹了mysql大小寫敏感導(dǎo)致程序無(wú)法啟動(dòng)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • MySQL主要使用的幾種索引算法小結(jié)

    MySQL主要使用的幾種索引算法小結(jié)

    本文主要介紹了MySQL主要使用的幾種索引算法小結(jié),包括B+Tree索引、Hash索引、Full-Text索引、R-Tree索引和Bitmap索引,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-02-02
  • MySQL使用navicat premium 15導(dǎo)出數(shù)據(jù)為批量插入格式實(shí)現(xiàn)方式

    MySQL使用navicat premium 15導(dǎo)出數(shù)據(jù)為批量插入格式實(shí)現(xiàn)方式

    本文介紹了使用Navicat進(jìn)行數(shù)據(jù)傳輸?shù)暮?jiǎn)要步驟,包括選擇數(shù)據(jù)傳輸工具、設(shè)置文件保存路徑、勾選“使用擴(kuò)展插入語(yǔ)句”選項(xiàng)、依次點(diǎn)擊下一步直至傳輸完成
    2025-10-10
  • 在MySQL中創(chuàng)建實(shí)現(xiàn)自增的序列(Sequence)的教程

    在MySQL中創(chuàng)建實(shí)現(xiàn)自增的序列(Sequence)的教程

    這篇文章主要介紹了在MySQL中創(chuàng)建實(shí)現(xiàn)自增的序列(Sequence)的教程,分別列舉了兩個(gè)實(shí)例并簡(jiǎn)單討論了一些限制因素,需要的朋友可以參考下
    2015-12-12
  • 保存圖片到MySQL以及從MySQL讀取圖片全過(guò)程

    保存圖片到MySQL以及從MySQL讀取圖片全過(guò)程

    有人喜歡使用mysql來(lái)存儲(chǔ)圖片,而有的人喜歡把圖片存儲(chǔ)在文件系統(tǒng)中,而當(dāng)我們要處理成千上萬(wàn)的圖片時(shí),會(huì)引起技術(shù)問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于如何保存圖片到MySQL以及從MySQL讀取圖片的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • MySQL定時(shí)備份到本地實(shí)現(xiàn)方式

    MySQL定時(shí)備份到本地實(shí)現(xiàn)方式

    項(xiàng)目使用mysqldump工具定時(shí)備份數(shù)據(jù)庫(kù)至本地,腳本mysql-backup.sh包含刪除歷史備份數(shù)據(jù)的命令,并通過(guò)定時(shí)任務(wù)實(shí)現(xiàn)自動(dòng)化備份流程,確保數(shù)據(jù)安全與存儲(chǔ)空間管理
    2025-09-09
  • 阿里云服務(wù)器手動(dòng)實(shí)現(xiàn)mysql雙機(jī)熱備的兩種方式

    阿里云服務(wù)器手動(dòng)實(shí)現(xiàn)mysql雙機(jī)熱備的兩種方式

    阿里云服務(wù)器由于不支持keepalive虛擬ip,導(dǎo)致無(wú)法通過(guò)keepalive來(lái)實(shí)現(xiàn)mysql的雙機(jī)熱備。我們這里要實(shí)現(xiàn)阿里云的雙機(jī)熱備有兩種方式。感興趣的朋友跟隨小編一起看看吧
    2019-10-10
  • MySQL高效處理ORDER BY與GROUP BY查詢的優(yōu)化策略

    MySQL高效處理ORDER BY與GROUP BY查詢的優(yōu)化策略

    在高并發(fā)、大數(shù)據(jù)量的業(yè)務(wù)場(chǎng)景中,SQL 查詢性能直接影響系統(tǒng)整體響應(yīng)速度,本文將深入探討 MySQL 中排序與分組的執(zhí)行機(jī)制,并提供一系列實(shí)用的優(yōu)化策略,希望對(duì)大家有所幫助
    2026-02-02

最新評(píng)論

鄄城县| 健康| 枣阳市| 高州市| 阳春市| 印江| 登封市| 汶上县| 邳州市| 满洲里市| 天长市| 平江县| 四川省| 蓬莱市| 高邑县| 南涧| 兴仁县| 上蔡县| 景洪市| 永嘉县| 天峻县| 基隆市| 梅州市| 烟台市| 蒙自县| 五原县| 长葛市| 土默特左旗| 改则县| 定襄县| 宁都县| 新河县| 喜德县| 丰宁| 德庆县| 酉阳| 儋州市| 长宁区| 南澳县| 盐山县| 莎车县|