MySQL的索引失效的原因有那些

1. 數據類型不匹配

詳細說明:MySQL在比較不同數據類型的值時,可能會嘗試進行隱式轉換。如果這種轉換導致了復雜度增加或無法直接利用索引,則會導致索引失效。

實例與解決方案

-- 錯誤示例:數據類型不匹配
select * from users where id = '123'; -- id 是 int 類型,'123' 是字符串-- 正確示例:確保數據類型一致
select * from users where id = 123; -- 使用正確的數據類型-- 如果必須使用字符串輸入,可以顯式轉換
select * from users where cast(id as char) = '123';

解決方案:確保查詢條件中的值與列的數據類型相匹配。如果必須使用不同類型的值,請顯式地進行類型轉換。在應用層面上,確保傳入數據庫的參數類型正確。

2. 隱式轉換

詳細說明:隱式轉換是指 mysql 自動將一個數據類型轉換為另一個數據類型。這種轉換可能改變原始的查詢模式,導致索引失效。

實例與解決方案

-- 錯誤示例:隱式轉換
select * from users where age = 25 + 0.0; -- 強制浮點數運算-- 正確示例:避免不必要的數學運算
select * from users where age = 25; -- 直接使用整數

解決方案:盡量保持查詢條件簡單明了,避免不必要的數學運算或其他可能導致隱式轉換的操作。編寫SQL語句時,確保數據類型一致性。

3. 函數或表達式

詳細說明:對索引列應用函數或復雜的表達式會阻止 mysql 使用該索引,因為它需要計算每一行的結果,從而失去了索引的優勢。mysql 8.0 引入了表達式索引(也稱為函數索引),可以在某些情況下幫助緩解這個問題。

實例與解決方案

-- 錯誤示例:索引列上使用函數
select * from articles where length(title) > 10;-- 改進方法(取決于需求)
select * from articles where title like '___________%'; -- 假設標題至少有11個字符-- 或者創建表達式索引(mysql 8.0+)
create index idx_title_length on articles ((length(title)));
select * from articles where length(title) > 10;

解決方案:盡可能避免在索引列上使用函數。如果必須這樣做,請考慮創建表達式索引或重新設計查詢邏輯。對于較老版本的MySQL,重構查詢以避免使用函數可能是唯一的選擇。

4. 范圍查詢之后的列

詳細說明:在復合索引中,一旦出現了范圍條件,mysql 就不能再使用后續的索引部分,因為這些部分不再能夠有效地縮小搜索范圍。復合索引的設計應該考慮到查詢模式。

實例與解決方案

create index idx_name on table (col1, col2);
select * from table where col1 = 'value1' and col2 > 'value2';-- 如果你經常需要基于 col2 的范圍查詢,可以考慮創建一個單獨的索引
create index idx_col2 on table (col2);

解決方案:對于頻繁使用的范圍查詢,應該單獨為涉及的列創建索引。同時,在設計復合索引時要考慮到查詢模式,盡量讓等值條件先于范圍條件出現。

5. like 查詢

詳細說明like 模式以通配符開頭時,mysql 不能使用索引來加速查詢,因為它需要掃描所有可能的前綴。然而,如果通配符出現在模式的末尾,則索引仍然可以被使用。

實例與解決方案

-- 不理想的查詢
select * from names where name like '%john%';-- 改進方法(根據實際情況)
-- 如果是尾部模糊匹配,可以使用索引
select * from names where name like 'john%';-- 或者使用全文索引(適用于大量文本搜索)
alter table names add fulltext(name);
select * from names where match(name) against('john');-- 對于前綴匹配,可以使用索引覆蓋
select * from names where name >= 'john' and name < 'johnz';

解決方案:盡量避免使用以通配符開頭的LIKE查詢。如果確實需要這樣的功能,可以考慮使用全文索引或者其他專門的搜索引擎。對于前綴匹配,可以通過范圍查詢實現索引的有效利用。

6. or 條件

詳細說明:使用 or 連接的不同列上的條件可能導致 mysql 無法有效利用索引,特別是當 or 條件跨越多個不同的列時。mysql 5.6 及以后版本支持索引合并策略,可以在某些情況下提高性能。

實例與解決方案

-- 不理想的查詢
select * from users where first_name = 'john' or last_name = 'smith';-- 改進方法(根據實際情況)
-- 如果查詢頻率較高,可以考慮創建組合索引
create index idx_first_last_name on users (first_name, last_name);-- 或者重構查詢邏輯,如使用 union
select * from users where first_name = 'john'
union all
select * from users where last_name = 'smith';-- 利用索引合并(mysql 5.6+)
explain select * from users where first_name = 'john' or last_name = 'smith';

解決方案:評估是否可以通過創建組合索引或者重構查詢邏輯來提高性能。對于某些情況,UNION可能是更好的選擇。檢查EXPLAIN輸出,看看是否啟用了索引合并。

7. 全表掃描更高效

詳細說明:對于非常小的表或者返回大部分行的查詢,全表掃描可能比使用索引更快,因為索引訪問涉及到額外的 i/o 操作。mysql 優化器會權衡利弊,決定最合適的執行計劃。

實例與解決方案

-- 對于小表,即使有索引也可能選擇全表掃描
select * from small_table;-- 對于大表,如果查詢返回大量行,優化器也會傾向于全表掃描
select * from large_table where some_condition;

解決方案:理解MySQL優化器的行為,不要盲目依賴索引。有時候,對于特定的小表或高覆蓋率查詢,全表掃描是最佳選擇。定期分析查詢性能,確保優化器做出正確的決策。

8. 索引選擇性低

詳細說明:選擇性低意味著索引列包含大量的重復值,使得索引的效果大打折扣。在這種情況下,mysql 可能會認為全表掃描更加高效。選擇性高的索引可以顯著提高查詢性能。

實例與解決方案

-- 性別列的選擇性很低
select * from employees where gender = 'm';-- 改善方法(根據實際情況)
-- 盡量避免在低選擇性的列上創建獨立的索引,除非它們與其他高選擇性的列一起組成復合索引
create index idx_gender_salary on employees (gender, salary);

解決方案:避免在選擇性低的列上創建獨立的索引。可以考慮與其他高選擇性的列組合成復合索引。通過analyze table命令獲取統計信息,評估索引的選擇性。

9. 覆蓋索引不足

詳細說明:當查詢中所選的列不在索引中時,mysql 必須回表獲取完整行信息,這增加了額外的 i/o 成本,降低了索引的效率。覆蓋索引可以顯著減少讀取時間。

實例與解決方案

-- 假設有一個覆蓋索引 idx_id_name 包含 id 和 name 列
select id, name, address from customers where id = 123;-- 改善方法
create index idx_id_name_address on customers (id, name, address);

解決方案:創建覆蓋索引,即包括查詢中所有需要的列。這樣可以在索引中直接獲取所需數據,而無需回表。注意,覆蓋索引雖然提高了讀取速度,但可能會影響寫入性能,因此需要平衡考慮。

10. 統計信息不準確

詳細說明:mysql 優化器依賴于表的統計信息來決定查詢計劃。如果這些統計數據過時或不準確,優化器可能會做出錯誤的決策。維護良好的統計信息對于優化查詢至關重要。

實例與解決方案

-- 分析表以更新統計信息
analyze table your_table;-- 或者使用 optimize table 來重建表并更新統計信息
optimize table your_table;-- 在 mysql 8.0 及以上版本,還可以使用系統變量控制統計信息的收集
set persist optimizer_switch='histogram=on';

解決方案:定期運行analyze tableoptimize table命令來保持統計信息的準確性。這對于大型表尤其重要。在MySQL 8.0及以上版本,可以啟用直方圖統計信息來更好地反映數據分布。

11. 鎖爭用

詳細說明:在高并發環境下,鎖機制的存在可能導致索引效率下降,即使有合適的索引也無濟于事。鎖定問題不僅影響索引效率,還可能導致其他并發問題,如死鎖。

實例與解決方案

-- 在高負載系統中,頻繁更新某張表可能會導致讀取操作等待寫鎖釋放
-- 解決方案包括但不限于調整事務隔離級別、優化 sql 語句減少鎖定時間等。-- 降低事務隔離級別以減少鎖定
set session transaction isolation level read committed;-- 使用樂觀鎖策略,如添加版本號列
alter table your_table add column version int default 0;
update your_table set column1 = value1, version = version + 1 where id = specific_id and version = current_version;

解決方案:優化SQL語句以減少鎖定時間,考慮適當的事務隔離級別,評估是否可以使用樂觀鎖策略。對于高并發環境,考慮分庫分表、讀寫分離等架構優化措施。

使用 mysql 工具進行診斷和優化

  • explain:使用?explain?關鍵字查看查詢執行計劃,了解 mysql 是如何處理你的查詢的。
  • show index:顯示表的索引信息,幫助評估現有索引的有效性和適用性。
  • performance_schema:監控和診斷 mysql 性能問題,包括鎖定、線程狀態等。
  • slow query log:記錄慢查詢日志,找出那些執行時間過長的查詢。
  • information_schema:訪問有關數據庫元數據的信息,如表結構、索引等。

? ? ? ?通過上述詳細的討論,我們可以看到,mysql 索引失效的問題往往可以通過合理的查詢優化、索引設計和維護來解決。了解你的數據分布、查詢模式以及 mysql 優化器的工作原理是構建高效數據庫應用的關鍵。持續監控和優化數據庫性能,確保索引得到充分利用,是保證應用程序響應快速和穩定的重要步驟。

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

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

相關文章

邁向未來:.NET技術的持續創新與發展前景

隨著信息技術的飛速發展&#xff0c;編程語言和開發框架不斷涌現&#xff0c;許多技術平臺以其獨特的優勢贏得了開發者的青睞。在這場技術的競爭中&#xff0c;.NET平臺憑借其卓越的性能、廣泛的生態系統以及持續創新的精神&#xff0c;成為了全球開發者的重要選擇。本文將探討…

微信小程序-基于Vant Weapp UI 組件庫的Area 省市區選擇

Area 省市區選擇&#xff0c;省市區選擇組件通常與 彈出層 組件配合使用。 areaList 格式 areaList 為對象結構&#xff0c;包含 province_list、city_list、county_list 三個 key。 每項以地區碼作為 key&#xff0c;省市區名字作為 value。地區碼為 6 位數字&#xff0c;前兩…

Canvas指定三角形內部生成隨機點

使用重心坐標&#xff08;barycentric coordinates&#xff09;或者通過面積比例的方法來確定點是否在三角形內。不過&#xff0c;對于簡單的應用&#xff0c;一種常見的方法是使用隨機點并檢查它們是否在三角形內部。如果不在&#xff0c;就重新生成&#xff0c;直到得到足夠數…

智駕感知「大破局」!新一輪混戰開啟

隨著智能駕駛搭載率的攀升&#xff0c;艙外傳感器賽道迎來新變局。 一方面&#xff0c;從近幾年智駕傳感器的配置變化來看&#xff0c;攝像頭的主導地位顯而易見。 12月10-12日&#xff0c;由德賽西威總冠名的2024&#xff08;第八屆&#xff09;高工智能汽車年會暨年度金球獎…

深入解析Android Recovery系統

深入解析Android Recovery系統 引言 在Android系統中,Recovery模式是一個非常重要的組成部分。它主要用于系統的恢復、更新和修復。當用戶遇到系統問題時,Recovery模式可以提供一種安全的方式來恢復系統到正常狀態。本文將深入探討Android Recovery系統的實現原理,重點分析…

Kibana8.17.0在mac上的安裝

1、Kibana是什么 Kibana是與elasticsearch配套使用的數據分析與可視化工具&#xff0c;通過Kibana可以輕松與es中存儲的數據進行高效的交互&#xff0c;包括數據寫入、檢索、刪除等操作&#xff0c;并可以通過編寫部分代碼將數據做成各種報表&#xff0c;從而進行非常直觀的統…

數字IC后端設計實現十大精華主題分享

今天小編給大家分享下吾愛IC社區星球上周十大后端精華主題。 Q1:星主&#xff0c;請教個問題&#xff0c;長tree的時候發現這個scan的tree 的skew差不多400p&#xff0c;我高亮了整個tree的schematic&#xff0c;我在想是不是我在這一系列mux前邊打斷&#xff0c;設置ignore p…

給bmp和png,設置BLENDFUNCTION的AlphaFormat不同參數的效果

BLENDFUNCTION是AlphaBlend用控制透明效果的重要參數。 選擇一個32位的png圖片&#xff0c;設置AlphaFormat 為 AC_SRC_ALPHA&#xff0c;效果如上圖。 選擇一個32位的png圖片&#xff0c;設置AlphaFormat 為 0&#xff0c;效果如上圖。 選擇一個24位的bmp圖片&#xff0c;設置…

ChildLife“童年時光杯”足球聯賽啟動 共促青少年健康成長

2024年12月21日至22日&#xff0c;由美國知名嬰幼兒營養品牌ChildLife童年時光贊助的“童年時光杯”青少年足球聯賽將在上海拉開帷幕。本次賽事U7/U8組別共有16支足球隊參賽&#xff0c;包括上海幸運星足球俱樂部旗下的明星球隊&#xff0c;以及其他青少年俱樂部的優秀隊伍&…

面向對象的基本原則【學習、記錄】

1、單一職責原則定義 一個對象應該只包含單一的職責&#xff0c;并且該職責被完整地封裝在一個類中。就一個類而言&#xff0c;應該僅有一個引起它變化的原因。 2、開閉原則定義 一個軟件實體應當對擴展開放&#xff0c;對修改關閉。 3、里氏代換原則定義 如果對每一個類型為S的…

什么是根服務器?有什么作用?

你知道什么是根服務器嗎?在互聯網的龐大架構中&#xff0c;根服務器很多人對它的了解并不深入。那么&#xff0c;根服務器到底是什么&#xff0c;它有什么作用呢? 什么是根服務器? 根服務器是互聯網域名系統(DNS)的一部分&#xff0c;負責管理和維護最頂層的域名信息。簡單…

MTK--mt7921 usb wifi debug

文章目錄 1、代碼編譯2、配置文件修改3、Wifi設置命令4、Wifi debug 淘寶隨便買個7921的usb wifi。 1、代碼編譯 export TEMPLATECONF${PWD}/meta/meta-mediatek-mt8518/conf/base/aud8518sp2-slc-32b-7921-c4a-user source meta/poky/oe-init-build-env bitbake mtk-image-au…

日志層次結構及logger.propagate的作用

一、Python logging 模塊的層次結構 Python 的 logging 模塊提供了一個靈活的日志系統&#xff0c;適用于各種規模的應用程序。其核心設計基于層次化的命名系統&#xff0c;使得日志記錄可以按照組織結構進行管理和配置。 1. Logger&#xff08;日志器&#xff09; 定義&…

如何配置OSB連接數據連接/讀取超時

1.Oracle DB OSB中的DBAdapter的查詢超時參數配置沒用&#xff0c;要解決接口超時問題&#xff0c;需要在console中的數據源配置超時參數&#xff1a; oracle.net.CONNECT_TIMEOUT30000 oracle.net.READ_TIMEOUT30000 添加圖片注釋&#xff0c;不超過 140 字&#xff08;可選…

一起學Git【第六節:查看版本差異】

git diff是 Git 版本控制系統中用于展示差異的強大工具。他可以用于查看文件在工作區、暫存區和版本庫之間的差異、任意兩個指定版本之間的差異和兩個分支之間的差異等,接下來進行詳細的介紹。 1.顯示工作區與暫存區之間的差異 # 顯示工作區和暫存區之間的差異,后面不加參數…

Python數據處理——re庫與pydantic的使用總結與實戰,處理采集到的思科ASA防火墻設備信息

目錄 Python正則表達式re庫的基本用法 引入re庫 各函數功能 總結 使用方法舉例 正則表達式語法與書寫方式 正則表達式的常用操作符 思科ASA防火墻數據 數據1 數據2 書寫正則表達式 Python中pydantic的使用 導入基礎數據模板 根據數據采集目標定義Pydantic數據類型…

Yolo11改進策略:Head改進|DynamicHead,利用注意力機制統一目標檢測頭部|即插即用

摘要 論文介紹 本文介紹了一種名為DynamicHead的模塊,該模塊旨在通過注意力機制統一目標檢測頭部,以提升目標檢測的性能。論文詳細闡述了DynamicHead的工作原理,并通過實驗證明了其在COCO基準測試上的有效性和效率。 創新點 DynamicHead模塊的創新之處在于它首次嘗試在一…

`we_chat_union_id IS NOT NULL` 和 `we_chat_union_id != ‘‘` 這兩個條件之間的區別

文章目錄 1、什么是空字符串&#xff1f;2、兩個引號之間加上空格 好的&#xff0c;我們來詳細解釋一下 we_chat_union_id IS NOT NULL 和 we_chat_union_id ! 這兩個條件之間的區別&#xff0c;以及它們在 SQL 查詢中的作用&#xff1a; 1. we_chat_union_id IS NOT NULL 含…

如何利用AWS監聽存儲桶并上傳到tg bot

業務描述&#xff1a; 需要監聽aws的存儲中的最新消息&#xff0c;發送新的消息推送到指定tg的頻道。 主要流程&#xff1a; 1.上傳消息到s3存儲桶&#xff08;不做具體描述&#xff09; 2.通過aws的lambda監聽s3存儲桶的最新消息&#xff08;txt文件&#xff09; 3.將txt文件…

HarmonyOS NEXT 實戰之元服務:靜態案例效果---查看國內航班服務

背景&#xff1a; 前幾篇學習了元服務&#xff0c;后面幾期就讓我們開發簡單的元服務吧&#xff0c;里面豐富的內容大家自己加&#xff0c;本期案例 僅供參考 先上本期效果圖 &#xff0c;里面圖片自行替換 效果圖1完整代碼案例如下&#xff1a; Index代碼 import { authen…