聯合索引失效情況分析

一.模擬表結構:

背景:

MySQL版本——8.0.37

表結構DDL:

CREATE TABLE `unite_index_table` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主鍵',`clomn_first` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '列1',`clomn_second` bigint NOT NULL COMMENT '列2',`clomn_third` bigint NOT NULL COMMENT '列3',`clomn_fourth` int NOT NULL COMMENT '列4',`clomn_fifth` bigint NOT NULL COMMENT '列5',`clomn_sixth` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '列6',`clomn_seventh` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '列7',`clomn_eighth` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '列8',`clomn_ninth` int NOT NULL COMMENT '列9',`clomn_tenth` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '列10',`clomn_eleventh` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '列11',`clomn_twelfth` bigint NOT NULL COMMENT '列12',`clomn_thirteenth` bigint NOT NULL COMMENT '列13',`clomn_fourteenth` bigint NOT NULL COMMENT '列14',`clomn_fifteenth` tinyint NOT NULL DEFAULT '1' COMMENT '列15',PRIMARY KEY (`id`),KEY `idx_clomn_fifth` (`clomn_fifth`),KEY `idx_unite` (`clomn_second`,`clomn_third`,`clomn_twelfth`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='模擬表';

表結構比較奇怪,是為了模擬實際生產的表結構,表結構信息進行脫敏;

?創建mock數據:
?

DROP PROCEDURE
IFEXISTS generate_mock_data;DELIMITER //
CREATE PROCEDURE generate_mock_data ( IN row_count INT ) BEGINDECLAREi INT DEFAULT 0;START TRANSACTION;-- 開始事務WHILEi < row_count DOINSERT INTO unite_index_table (clomn_first,clomn_second,clomn_third,clomn_fourth,clomn_fifth,clomn_sixth,clomn_seventh,clomn_eighth,clomn_ninth,clomn_tenth,clomn_eleventh,clomn_twelfth,clomn_thirteenth,clomn_fourteenth,clomn_fifteenth )VALUES(SUBSTRING( MD5( RAND( ) ), 1, 20 ),FLOOR( RAND( ) * 10000000000 ),FLOOR( RAND( ) * 10000000000 ),FLOOR( RAND( ) * 100000 ),FLOOR( RAND( ) * 10000000000 ),SUBSTRING( MD5( RAND( ) ), 1, 64 ),IF( RAND( ) > 0.5, SUBSTRING( MD5( RAND( ) ), 1, 64 ), NULL ),IF( RAND( ) > 0.5, SUBSTRING( MD5( RAND( ) ), 1, 20 ), NULL ),FLOOR( RAND( ) * 256 ),IF( RAND( ) > 0.5, SUBSTRING( MD5( RAND( ) ), 1, 1024 ), NULL ),IF( RAND( ) > 0.5, SUBSTRING( MD5( RAND( ) ), 1, 64 ), NULL ),FLOOR( RAND( ) * 10000000000 ),UNIX_TIMESTAMP( ),UNIX_TIMESTAMP( ),FLOOR( RAND( ) * 2 ) );SET i = i + 1;END WHILE;COMMIT;-- 提交事務END // 
DELIMITER;
CALL generate_mock_data ( 1000000 );
DROP PROCEDURE
IFEXISTS generate_mock_data;

?二.不同情況下的查詢:

背景補充:

1.做模擬查詢的時候,如果使用區間查詢(>,>=,<,<=,!=,between and),區間查詢的值需要再表中存在,而不是超出區間,不然可能會導致explain分析該SQL會使用索引(實則為查詢值越界)

補充:

摘自MySQL官網
key_len?(JSON name:?key_length)

The?key_len?column indicates the length of the key that MySQL decided to use. The value of?key_len?enables you to determine how many parts of a multiple-part key MySQL actually uses. If the?key?column says?NULL, the?key_len?column also says?NULL.

Due to the key storage format, the key length is one greater for a column that can be?NULL?than for a?NOT NULL?column.

2.key_len 的計算基于索引中每列的數據類型、字符集以及是否允許 NULL。以下是一些常見數據類型的索引長度:

  • INT:4 字節。
  • BIGINT:8 字節。
  • VARCHAR(n):根據字符集計算。例如,utf8mb4 字符集下,VARCHAR(20) 可能占用 n * 4 字節(utf8mb4 每個字符最多 4 字節)。
  • CHAR(n):與 VARCHAR 類似,但 CHAR 是固定長度。
  • 如果列允許 NULL,則會額外增加 1 字節(用于存儲 NULL 標志)。

在聯合索引中,key_len 是查詢中實際用到的索引列的長度之和。MySQL 會根據查詢條件和最左匹配原則,決定使用索引的前幾列。

key_len展示所使用到的索引key的長度,會根據具體使用到的索引的聯合索引的key個數以及索引列的類型發生變化;

例如:

僅使用首列索引;
?使用所有索引列;

能使用到索引的情況:

1.使用索引的首列等值查詢和第三列區間查詢:

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_twelfth >= 7827883584 AND clomn_second = 2058342613
SQL Explain
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tablerefidx_uniteidx_unite8const57433.33Using index condition

?分析得出,因為使用了聯合索引的第一列,所以查詢是使用到了索引,具體使用情況為:Using index condition

聯合索引哪怕是僅用到了索引首列,也是可以走索引優化查詢(另外提一嘴,是否走聯合索引和where條件后的列先后順序無關,最左匹配和查詢時列索引順序毫無關系,MySQL對SQL會進行解釋器優化);

2.使用索引首列等值查詢,第二列區間查詢,第三列區間查詢

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_twelfth != 3665470530 AND clomn_second = 6132267663 AND clomn_third >= 845697131
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tablerangeidx_uniteidx_unite16190Using index condition

使用到了索引,key_len為16,表名使用了索引的首列和次列;

補充說明:

//將clomn_second全部設置為1,讓索引列失去特異性,驗證第一種情況是否仍然成立:

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_twelfth >= 7827883584 AND clomn_second = 1
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tablerefidx_uniteidx_unite8const30421633.33Using index condition

?雖然索引失去了特異性,仍然使用了索引,但是此時的key_len變成了8;

//再將clomn_third全部設置為2,讓索引列失去特異性,驗證第二種情況是否仍然成立:

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_twelfth != 3665470530 AND clomn_second = 1 AND clomn_third = 2
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tableALLidx_unite606845100Using where

?出乎意料的,聯合索引第一列索引和第二列索引列同時失去特異性后,導致查詢不能夠走到索引,造成全表掃描

不能使用到索引的情況:

1.索引第一列為區域查詢(帶有>或者<),不包含其他列

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_second > 251963017
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tableALLidx_unite61074250Using where

查詢僅帶有首列的區間查詢,?查詢不能走聯合索引

2.索引第一列為區間查詢(帶有>或者<)

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_second > 251963017 AND clomn_third = 5251684771
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tableALLidx_unite6107425Using where

因為首行非等值查詢,而是區間查詢,且有其他查詢列,聯合查詢不走索引(上一個示例都不會索引,這個更不會)

3.使用聯合索引的第二列和第三列

EXPLAIN SELECT* 
FROMunite_index_table 
WHEREclomn_third = 5251684771 AND clomn_twelfth > 2058342
idselect_typetablepartitionstypepossible_keyskeykey_lenrefrowsfilteredExtra
1SIMPLEunite_index_tableALL6107423.33Using where

由于沒有篩選首列,聯合索引沒能走到聯合索引的優化,即通常講的不滿足最左匹配原則;

三.總結:

總體結論
  1. 首列等值查詢是關鍵
    • 只要首列(clomn_second)使用等值查詢(=),即使后續列使用區間查詢(>、>=)或不等值查詢(!=),聯合索引仍可使用。
  2. 首列區間查詢導致索引失效
    • 當首列使用區間查詢(>、<等),無論后續列條件如何,聯合索引無法使用,導致全表掃描。
  3. 最左匹配原則
    • 聯合索引必須從首列開始匹配,跳過首列直接查詢后續列無法利用索引。
  4. 特異性影響
    • 首列失去特異性時,索引仍可使用,但性能下降(掃描行數增加)。
    • 首列和后續列均失去特異性時,索引可能失效,導致全表掃描。
  5. 查詢條件順序無關
    • WHERE子句中列的順序不影響索引使用,MySQL優化器會自動調整。
建議:
  1. 索引設計
    • 將常用等值查詢的列放在聯合索引的前列,確保滿足最左匹配原則。
    • 避免將區間查詢列作為索引首列
  2. 特異性優化
    • 確保索引列具有足夠的區分度,避免值重復率過高。
    • 定期分析數據分布,調整索引策略。
  3. 查詢優化
    • 優先使用等值條件過濾首列數據,再處理范圍條件。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/83958.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83958.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/83958.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

軟件架構之-論分布式架構設計及其實現

論分布式架構設計及其實現 摘要正文摘要 2023年2月,本人所在集團公司承接了長三角地區某省漁船圖紙電子化審查項目開發,該項目旨在為長三角地區漁船建造設計院、漁船審圖機構提供一個便捷化的服務平臺。在次項目中,我作為項目成員參與了整個項目的建設工作,全權負責項目需求…

Pydantic數據驗證實戰指南:讓Python應用更健壯與智能

導讀&#xff1a;在日益復雜的數據驅動開發環境中&#xff0c;如何高效、安全地處理和驗證數據成為每位Python開發者面臨的關鍵挑戰。本文全面解析了Pydantic這一革命性數據驗證庫&#xff0c;展示了它如何通過聲明式API和類型提示系統&#xff0c;徹底改變Python數據處理模式。…

3、ubantu系統 | 通過vscode遠程安裝并配置anaconda

1、vscode登錄 登錄后通過pwd可以發現目前位于wangqinag賬號下&#xff0c;左側為屬于該賬號的文件夾及文件。 通過cd ..可以回到上一級目錄&#xff0c;通過ls可以查看當前目錄下的文件夾及文件。 2、安裝 2.1、下載anaconda 通過wget和curl下載未成功&#xff0c;使用手動…

Python 與 Java 在 Web 開發中的深度對比:從語言特性到生態選型

在 Web 開發領域&#xff0c;Python 和 Java 作為兩大主流技術棧&#xff0c;始終是開發者技術選型時的核心考量。本文將從語言本質、框架生態、性能工程、工程實踐等多個維度展開深度對比&#xff0c;結合具體技術場景解析兩者的適用邊界與融合方案&#xff0c;為開發者提供系…

【OpenGL學習】(一)創建窗口

文章目錄 【OpenGL學習】&#xff08;一&#xff09;創建窗口 【OpenGL學習】&#xff08;一&#xff09;創建窗口 GLFW OpenGL 本身只是一套圖形渲染 API&#xff0c;不提供窗口創建、上下文管理或輸入處理的功能。 GLFW 是一個支持創建窗口、處理鍵盤鼠標輸入和管理 OpenGL…

電腦閃屏可能的原因

1. 顯示器 / 屏幕故障 屏幕排線接觸不良&#xff1a;筆記本電腦屏幕排線&#xff08;屏線&#xff09;松動或磨損&#xff0c;導致信號傳輸不穩定&#xff0c;常見于頻繁開合屏幕的設備。屏幕面板損壞&#xff1a;液晶屏內部燈管老化、背光模塊故障或面板本身損壞&#xff0c;…

docker容器知識

一、docker與docker compose區別&#xff1a; 1、docker是創建和管理單個容器的工具&#xff0c;適合簡單的應用或服務&#xff1b; 2、docker compose是管理多容器應用的工具&#xff0c;適合復雜的、多服務的應用程序&#xff1b; 3、docker與docker compose對比&#xff…

什么是Rootfs

Rootfs (Root Filesystem) 詳解 buildroot工具構建了一個名為"rootfs.tar"的根文件系統壓縮包。 什么是rootfs Rootfs&#xff08;Root Filesystem&#xff0c;根文件系統&#xff09;是操作系統啟動后掛載的第一個文件系統&#xff0c;它包含系統正常運行所需的基…

關于NLP自然語言處理的簡單總結

參考&#xff1a; 什么是自然語言處理&#xff1f;看這篇文章就夠了&#xff01; - 知乎 (zhihu.com) 所謂自然語言理解&#xff0c;就是研究如何讓機器能夠理解我們人類的語言并給出一些回應。 自然語言處理&#xff08;Natural Language Processing&#xff0c;NLP&#xff0…

Linux下載國外軟件鏡像的加速方法(以下載Python-3.8.0.tgz為例)

0 前言 使用linux經常會通過國外服務器下載軟件鏡像&#xff0c;有些軟件的下載速度奇慢&#xff0c;本文介紹一種加速國外軟件鏡像下載速度的方法&#xff0c;需要準備下載工具&#xff1a;迅雷。 1 以下載Python-3.8.0.tgz為例 找到Python官網的Python-3.8.0.tgz鏡像下載地…

沒有公網ip怎么端口映射外網訪問?使用內網穿透可以解決

無公網IP時本地搭建的網絡端口服務怎么映射外網遠程訪問&#xff1f;較為簡單通用的方案就是使用nat123內網穿透&#xff0c;下面詳細內網映射外網實現教程。? 一、了解內網公網區別&#xff0c;及無公網IP外網訪問方案 內網IP默認只能在同局域網內連接互通&#xff0c;而公…

Word2Vec詳解

目錄 Word2Vec 一、Word2Vec 模型架構 &#xff08;一&#xff09;Word2Vec 的核心理念 &#xff08;二&#xff09;Word2Vec 的兩種架構 &#xff08;三&#xff09;負采樣與層次 Softmax &#xff08;四&#xff09;Word2Vec 的優勢與局限 二、Word2Vec 預訓練及數據集…

ShardingSphere:查詢報錯:Actual table `數據源名稱.表名` is not in table rule configuration

目錄 簡介異常信息排查原因解決 簡介 1、使用ShardingSphere框架&#xff0c;版本為5.2.1 <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core</artifactId><version>5.2.1</version>…

MongoDB聚合查詢:從入門到精通

文章目錄 前言一、工具一般聚合查詢分為四步 二、使用步驟1.MongoDB Compass2.Studio 3T 二、舉個栗子總結 前言 Mongo 聚合查詢 一般用mongo做數據庫,涉及到關聯查詢情況不多,但是還有些情況要使用到,今天就講下如何通過工具做關聯查詢,最終聚合結果,得到最終的查詢結果集; …

codeup添加流水線docker自動化部署

在項目根目錄下增加Dockerfile文件 # 使用基礎鏡像 FROM maven:3.8.4-openjdk-17-slim AS build # 設置工作目錄 WORKDIR /app # 復制項目源代碼 COPY . . # 構建項目 RUN mvn clean package -DskipTests # 驗證JAR包是否生成 RUN ls -l target/your-project.jar # 使用合適的…

從 Word2Vec 到 BERT:AI 不止是詞向量,更是語言理解

一、前言 在上篇文章中&#xff0c;我們介紹了Word2Vec以及它的作用&#xff0c;總的來說&#xff1a; Word2Vec是我們理解NLP的第一站 Word2Vec將詞變成了“向量”—— 終于可以用機器理解詞語的相似度 我們獲得了例如“國王 - 男人 女人 ≈ 女王” 的類比能力 我們可以將…

鏡像管理(2)Dockerfile總結

一、docker鏡像構建方法 commoit :使用 docker commit 意味著所有對鏡像的操作都是黑箱操作,生成的鏡像也被稱為黑 箱鏡像,換句話說,就是除了制作鏡像的人知道執行過什么命令、怎么生成的鏡像,別人根 本無從得知。而且,即使是這個制作鏡像的人,過一段時間后也無法記清具…

機器學習第十七講:PCA → 把100維數據壓縮成3D視圖仍保持主要特征

機器學習第十七講&#xff1a;PCA → 把100維數據壓縮成3D視圖仍保持主要特征 資料取自《零基礎學機器學習》。 查看總目錄&#xff1a;學習大綱 關于DeepSeek本地部署指南可以看下我之前寫的文章&#xff1a;DeepSeek R1本地與線上滿血版部署&#xff1a;超詳細手把手指南 主…

【Linux庖丁解牛】——進程等待!

1. 進程退出場景 進程退出一般有三種場景&#xff1a; 。代碼運行完畢&#xff0c;結果正確 。代碼運行完畢&#xff0c;結果錯誤【比如&#xff0c;我們要對某個文件進行寫入&#xff0c;但寫入的文件路徑出錯&#xff0c;代碼運行完畢&#xff0c;可是結果出錯】 。代碼異…

鴻蒙OSUniApp 制作簡潔高效的標簽云組件#三方框架 #Uniapp

UniApp 制作簡潔高效的標簽云組件 在移動端應用中&#xff0c;標簽云&#xff08;Tag Cloud&#xff09;是一種常見的UI組件&#xff0c;它以視覺化的方式展示關鍵詞或分類&#xff0c;幫助用戶快速瀏覽和選擇感興趣的內容。本文將詳細講解如何在UniApp框架中實現一個簡潔高效的…