mysql一張表,其中一個字段設置了唯一索引,又設置了普通索引,查詢的時候很慢,沒有走普通索引,是const

問題分析

在 MySQL 中,當一個字段同時存在唯一索引和普通索引時,查詢優化器通常會優先選擇最嚴格的索引(即能最快縮小結果集的索引)。在你的場景中,優化器選擇了唯一索引并將查詢視為const類型,這通常是高效的,但實際性能卻不理想。

唯一索引導致全索引掃描:如果查詢需要返回其他字段,即使使用唯一索引,也可能需要回表或全索引掃描。

問題就是出在這!

事實上走了唯一索引,很慢,我把唯一索引刪了,走普通索引就很快,但是我又希望確保這個字段的唯一性,怎么辦

解決方案:保留唯一性約束但優化索引使用

你遇到的情況很常見:唯一索引雖然保證了數據唯一性,但在某些查詢模式下可能不如普通索引高效。以下是幾種保留唯一性約束同時提升查詢性能的方法:

方案一:復合索引優化(推薦)

原理:創建包含唯一字段和常用查詢字段的復合索引,讓優化器選擇更合適的索引路徑。

示例
假設表結構如下:

sql

CREATE TABLE users (id INT PRIMARY KEY,unique_id VARCHAR(20) UNIQUE,  -- 導致性能問題的唯一索引name VARCHAR(50),age INT,INDEX idx_name_age (name, age)  -- 普通復合索引
);

優化步驟

  1. 刪除原唯一索引

    sql

    ALTER TABLE users DROP INDEX unique_id;
    
  2. 創建包含唯一性約束的復合索引

    sql

    CREATE UNIQUE INDEX idx_unique_id_name ON users (unique_id, name);
    
  3. 查詢優化

    sql

    -- 原查詢(可能變慢)
    SELECT * FROM users WHERE name = 'John';-- 優化后查詢(利用復合索引)
    SELECT unique_id, name FROM users WHERE name = 'John';
    

優勢

  • 保留了unique_id的唯一性約束
  • 復合索引可同時滿足唯一性和查詢性能需求
  • 覆蓋索引避免回表,提升查詢效率
方案二:觸發器實現唯一性檢查

原理:通過觸發器手動檢查插入 / 更新操作的唯一性,替代數據庫級別的唯一索引。

示例

sql

-- 創建觸發器確保唯一性
DELIMITER $$
CREATE TRIGGER check_unique_id
BEFORE INSERT ON users
FOR EACH ROW
BEGINIF EXISTS (SELECT 1 FROM users WHERE unique_id = NEW.unique_id) THENSIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Duplicate entry for unique_id';END IF;
END$$
DELIMITER ;

優勢

  • 完全移除唯一索引,釋放索引維護開銷
  • 查詢可自由使用普通索引

注意事項

  • 觸發器會增加插入 / 更新的開銷
  • 并發寫入時可能出現競態條件(需配合事務)
  • 建議結合應用層唯一性檢查使用
方案三:應用層保證唯一性

原理:在應用代碼中實現唯一性檢查,而非依賴數據庫。

示例偽代碼

python

運行

# Python示例
def create_user(unique_id, name):# 1. 開始事務with db.transaction():# 2. 檢查唯一性existing = User.query.filter_by(unique_id=unique_id).first()if existing:raise ValueError("Unique ID already exists")# 3. 插入數據user = User(unique_id=unique_id, name=name)db.session.add(user)db.session.commit()

優勢

  • 數據庫完全不維護唯一索引,查詢性能最優
  • 靈活性高,可自定義錯誤處理邏輯

注意事項

  • 需要強事務保證(Serializable 隔離級別或行鎖)
  • 高并發場景下性能可能受影響
  • 必須在所有寫入路徑中統一實現檢查
方案四:哈希索引優化

原理:對唯一字段生成哈希值,用哈希值的唯一索引替代原始字段的唯一索引。

示例

sql

-- 添加哈希字段
ALTER TABLE users ADD COLUMN unique_id_hash INT;-- 計算哈希值并創建唯一索引
UPDATE users SET unique_id_hash = CRC32(unique_id);
CREATE UNIQUE INDEX idx_unique_hash ON users (unique_id_hash);-- 觸發器自動維護哈希值
DELIMITER $$
CREATE TRIGGER update_hash
BEFORE INSERT ON users
FOR EACH ROW
BEGINSET NEW.unique_id_hash = CRC32(NEW.unique_id);
END$$
DELIMITER ;

查詢優化

sql

-- 原始查詢(走普通索引)
SELECT * FROM users WHERE name = 'John';-- 唯一性檢查(走哈希唯一索引)
SELECT 1 FROM users WHERE unique_id_hash = CRC32('test_id');

優勢

  • 哈希索引更小、查詢更快
  • 保留了唯一性約束
  • 原始字段可自由使用普通索引

注意事項

  • 哈希碰撞概率(雖然極低,但需處理)
  • 額外存儲開銷
  • 插入 / 更新性能略有下降

最佳實踐建議

  1. 優先選擇復合索引:如果查詢模式固定,復合索引是最簡單有效的方案。

  2. 監控索引使用情況:定期使用EXPLAIN分析關鍵查詢,確保優化器選擇預期的索引。

  3. 分區表考慮:如果表數據量極大,可考慮按unique_id進行哈希分區,分散索引負載。

  4. 讀寫分離:對唯一性要求極高但讀多寫少的場景,可將唯一性檢查放在從庫進行。

根據你的具體業務場景選擇最合適的方案,通常復合索引能在保留約束的同時提供良好的性能。

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

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

相關文章

ARCGIS國土超級工具集1.6更新說明

ARCGIS國土超級工具集V1.6版本,功能已增加至60 個。本次更新在V1.5版本的基礎上,除修復了使用時發現的若干小問題外,還更新及新增了若干工具。其中勘測定界工具欄更新了界址點西北角重排工具,新增了提示圖斑起始點、指定圖斑起始點…

零基礎學習RabbitMQ(2)--Linux安裝RabbitMQ

注意:這里使用的是ubuntu系統 1. 安裝Erlang RabbitMQ需要Erlang語言的支持,在安裝rabbitMQ之前需要安裝Erlang #更新軟件包 sudo apt-get update #安裝erlang sudo apt-get install erlang 安裝后輸入 rel可查看Erlang版本: 輸入halt().…

Centos進單用戶模式

一、開機按E 二、修改里面的linux行 把ro 修改成rw init/sysroot/bin/sh 修改前: 修改后: 三、ctrl x退出,進入單用戶模式

RabbitMQ 的工作流程

RabbitMQ 是一個消息中間件,實現了生產者消費者模型,可以用來接收、存儲、轉發消息。 專有名詞介紹 要了解 RabbitMQ 的工作流程,我們需要先了解下面幾個關鍵詞: 1、Producer 生產者,即向 RabbitMQ 發送消息。 2…

HTTP——不同版本區別

目錄 HTTP1.0和HTTP1.1的區別 HTTP1.1相比HTTP1.0性能上的改進: 但是HTTP1.1還是有性能瓶頸: HTTP/2做了什么優化? HTTP/3的優點 HTTP與HTTPS的區別 HTTPS的工作原理 1.ClientHello 2.ServerHello 3.客戶端回應 4.服務器的最后回應…

關于M0+芯片的IAP應用導致延時不準確解釋

前言:在給項目中使用的M0芯片做IAP功能時一切一切都是那么的自然水到渠成,但是筆者在實現完IAP功能后,卻發現APP端掛載的單總線功能崩潰了,最開始沒有懷疑是bootload導致的。因為筆者在使用同一篇代碼的時候單總線掛載的設備不同&…

安卓登錄學習筆記

1. 背景與目標 (Background and Goal) 背景: 我們要創建一個用戶登錄界面。用戶輸入用戶名和密碼,點擊“登錄”按鈕。應用會顯示一個加載中的“圈圈”(ProgressBar),然后模擬一個耗時2秒的網絡請求。根據請求結果,界面…

Git(三):分支管理

文章目錄 Git(三):分支管理理解分支創建分支切換分支合并分支刪除分支合并沖突分支管理策略分支策略Bug分支刪除臨時分支 Git(三):分支管理 理解分支 本章介紹Git的殺手級功能之一:分支 分支就 是科幻電影里面的平行宇宙,當你正…

電子電氣架構 --- 電氣架構基礎(汽車電子)

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

RestClient 功能介紹、完整使用示例演示, 和RestTemplate、WebClient 對比

RestClient功能介紹 RestClient是Spring Framework 6.1版本引入的同步HTTP客戶端,旨在替代老舊的RestTemplate,提供更現代、流暢的API設計。其核心特點包括: 流暢API(Fluent API): 支持鏈式調用&#xff0…

VM經常遇見的運行慢幾種情況、以及設置方法

大家好,我是東哥說-MES 啟動虛擬機是提示如下內容 “無法打開內核設備“\.\VMCIDev\VMX”: 操作成功完成。是否在安裝 VMware Workstation 后重新引導? 模塊“DevicePowerOn”啟動失敗。 未能啟動虛擬機。” 2.用記事本打開安裝目錄下TIA Portal STEP7 Prof Safety WinCC …

【C++語法】類和對象(4)——日期類和const成員函數

6.類和對象&#xff08;4&#xff09; 文章目錄 6.類和對象&#xff08;4&#xff09;回顧簡單日期類的實現代碼補充&#xff1a;前置與后置的重載區別補充&#xff1a;關于流插入運算符&#xff08;<<&#xff09;的解釋拓展&#xff1a;仿照流插入操作符(<<)的作…

當凌晨的鍵盤聲,遇見黎明的星光?

地鐵玻璃映出你困倦的臉&#xff0c;耳機里的音樂循環到第 17 遍&#xff0c;早高峰的人群像沙丁魚罐頭般擠壓著你。這是你每天雷打不動的三小時通勤路&#xff0c;從城市邊緣到寫字樓林立的 CBD&#xff0c;窗外的風景換了四季&#xff0c;而你始終困在搖晃的車廂里&#xff0…

Web Worker技術詳解與應用場景

我們來詳細探討一下 Web Worker。它是現代 Web 開發中解決 JavaScript 單線程限制、提升應用性能和響應能力的關鍵技術。 核心問題&#xff1a;JavaScript 的單線程模型 瀏覽器 UI 線程&#xff08;主線程&#xff09;&#xff1a;JavaScript 在瀏覽器中默認運行在單個線程&a…

React Next快速搭建前后端全棧項目并部署至Vercel

很好&#xff0c;你是想搞清楚Next.js 的后端結構和傳統 Node Express 的區別對比&#xff0c;我來整理一套結構化、精準、對面試有說服力的解答&#xff0c;并附示意結構圖。 01Next vs Express 、## ??1?? Next.js 后端是怎么構建的 Next.js 在默認情況下本身就集成后…

【T寶客戶項目解決過程】01-模型訓練

1 項目需求描述 博主自己開了一家T寶店&#xff0c;有一個客戶有這個需求&#xff1a;有一大堆圖像&#xff0c;大概有10多萬張圖&#xff0c;都是比較小尺寸的圖。各種類型都有&#xff0c;我們想要通過將不同類型發圖像進行分開&#xff0c;如何實現呢&#xff1f; 2 思路 …

如何在中將網絡改為橋接模式并配置固定IP地址

在使用服務器搭建虛擬機的過程中&#xff0c;我們發現有許多場景需要將虛擬機的網絡配置為橋接模式&#xff0c;并為其設置固定的IP地址。為了幫助大家更高效地進行網絡配置&#xff0c;提升虛擬機的連接穩定性和管理便捷性&#xff0c;我們總結了這篇指南&#xff0c;介紹如何…

強化學習 - 基于策略的Reinforce算法

&#x1f3af; REINFORCE 策略梯度算法推導&#xff08;完整&#xff09; 1. 目標函數定義 我們希望最大化策略的期望回報&#xff1a; J ( θ ) E τ ~ π θ [ R ( τ ) ] J(\theta) \mathbb{E}_{\tau \sim \pi_\theta} \left[ R(\tau) \right] J(θ)Eτ~πθ??[R(τ…

Windows Sever Core安裝及常用命令

一、Windows Sever Core 在安裝 Windows Server 的過程中&#xff0c;可以選擇“Server Core”&#xff08;核心安裝&#xff09;這種沒有圖形用戶界面&#xff08;GUI&#xff09;的安裝方式。這種模式下&#xff0c;Windows Server 主要通過命令行或遠程管理進行配置和維護&…

Java 單元測試實戰:以“兩數之和”為例,講透測試思維

&#x1f31f;Java 單元測試實戰&#xff1a;以“兩數之和”為例&#xff0c;講透測試思維 在 Java 開發中&#xff0c;單元測試不僅是驗證功能正確的手段&#xff0c;更是衡量開發者是否具備“測試思維”的標志。今天我們通過一個最簡單的功能——“兩數之和”來系統講解如何…