MySQL之創建高性能的索引(六)

創建高性能的索引

選擇合適的索引列順序

當使用前綴索引的時候,在某些條件值的基數比正常值高的時候,問題就來了。例如,在某些應用程序中,對于沒有登錄的用戶,都將其用戶名記錄為"guest",在記錄用戶行為的會話(session)表和其他記錄用戶活動的表中"guest"就成為了一個特殊用戶ID.一旦查詢涉及這個用戶,那么和對于正常用戶的查詢就大不同了,因為通常由很多會話都是沒有登錄的。系統賬號也會導致類似的問題。一個應用通常都有一個特殊的管理員賬號,和普通賬號不同,它并不是一個具體的用戶,系統中所有的其他用戶都是這個用戶的好友,所以系統往往通過它向網站的所有用戶發送狀態通知和其他消息。這個賬號的巨大的好友列表很容易導致網站初夏你服務器性能問題。這實際上是一個非常典型的問題。任何的異常用戶,不僅僅是那些用于管理應用的設計糟糕的賬號會有同樣的問題;那些擁有大量好友、圖片、狀態、收藏的用戶,也會有前面提到的系統賬號同樣的問題。下面s是一個真實案例,在一個用戶分享購買商品和購買經驗的論壇上,這個特殊表上的查詢運行得非常慢:

mysql> SELECT  COUNT(DISTINCT threadId) AS COUNT_VALUE FROM Message-> WHERE (groupId = 10137) AND (userId = 1288826) AND (anonymous = 0)-> ORDER BY priority DESC, modifiedDate DESC-> ;

這個查詢看似沒有建立合適的索引,所以客戶咨詢是否可以優化。EXPLAIN的結果如下:

id:1
select_type:SIMPLE
table:Message
type:ref
key:idx_groupId_userId
key_len:18
ref:const,const
rows:1251162
Extra:Using where

MySQL為這個查詢選擇了索引(groupId, userId),如果不考慮列的基數,這看起來是一個非常合理的選擇。但如果考慮一下userID和groupID條件匹配的行數,可能就會有不同的想法了:

mysql> SELECT COUNT(*) , SUM(groupId=10137), SUM(userId=1288826),SUM(anonymous = 0)-> FROM Message\G
*************************** 1. row ***************************
COUNT(*):4142217
SUM(groupId=10137):4092654
SUM(userId=1288826):1288496
SUM(anonymous=0):4141934

從上面的結果來看符合組(groupId)條件幾乎滿足表中的所有行,符合用戶(userId)條件的有130彎條記錄——也就是說索引基本上沒什么用。因為這些數據是從其他應用中遷移過來的,遷移的時候把所有的消息都賦予了管理員組的用戶。這個案例的解決辦法是修改應用程序代碼。去分這類特殊用戶和組,禁止針對這類用戶和組執行這個查詢。從這個小案例可以看到經驗法則和推論在多數情況下是有用的,但要注意不要假設平均情況下的性能也能代表特殊情況下的性能,特殊情況可能會摧毀整個應用的性能。最后,盡管關于選擇性和基數的經驗法則值得去研究和分析,但一定要記住別忘了WHERE子句中的排序、分組和范圍條件等其他因素,這些因素可能對查詢的性能造成非常大的影響。

聚簇索引

在這里插入圖片描述

聚簇索引并不是一種單獨的索引類型,而是一種數據存儲方式。具體的細節依賴于其實現方式但InnoDB得聚簇索引實際上在同一個結構中保存了B-Tree索引和數據行。當表有聚簇索引時,它的數據行實際上存放在索引的葉子頁(leaf page)中。術語"聚簇"表示數據行和相鄰的鍵值緊湊地存儲在一起。因為無法同時把數據行存放在兩個不同的地方,所以一個表只能有一個聚簇索引(不過,覆蓋索引可以模擬多個聚簇索引的情況)。因為是存儲引擎負責實現索引,因此不是所有的存儲引擎都支持聚簇索引。主要關注InnoDB.如圖展示了聚簇索引中的記錄是如何存放的。注意到,葉子頁包含了行的全部數據,但是節點頁只包含了索引列。該圖中,索引包含的是整數值。
一些數據庫服務器允許選擇哪個索引作為聚簇索引,但是目前市場上,還沒有任何一個MySQL內建的存儲引擎支持這一點。InnoDB將通過主鍵聚集數據,這也就是說上圖中的"被索引的列"就是主鍵列。如果沒有定義主鍵,InnoDB會選擇一個唯一的非空索引代替。如果沒有這樣的素銀,InnoDB會隱式定義一個主鍵來作為聚簇索引,InnoDB只聚集在同一個頁面中的記錄。包含相鄰鍵值的頁面可能會相距甚遠。
聚簇索引可能對性能有幫助,但也可能導致嚴重的性能問題。所以需要仔細地考慮聚簇素銀,尤其是將表的存儲引擎從InnoDB改成其他引擎的時候(反過來也一樣)。聚集的數據有一些重要的優點:

  • 1.可以把相關數據保存在一起。例如實現電子郵箱時,可以根據用戶ID來聚集數據,這樣只需要從磁盤讀取少數的數據也就能獲取某個用戶的全部郵件。如果沒有使用聚簇索引,則每封郵件都可能導致一次磁盤IO
  • 2.數據訪問更快。聚簇索引將索引和數據保存在同一個B-Tree中,因此聚簇索引中獲取數據通常比在非聚簇索引中查找要快。
  • 3.使用覆蓋索引掃描的查詢可以直接使用葉節點中的主鍵值
    如果在設計表和查詢時能充分利用上面的優點,那就能極大地提升性能。

同時,聚簇索引也有一些缺點:

  • 1.聚簇數據最大限度地提高了IO密集型應用的性能,但入股哦數據全部都存放在內存中,則訪問的順序就沒那么重要了,聚簇索引也就沒什么優勢了
  • 2.插入速度嚴重依賴于插入順序。按照主鍵的順序插入是加載數據到InnoDB表中速度最快的方式。但如果不是按照主鍵順序加載數據,那么在加載完成后最好使用OPTIMIZE TABLE命令重新組織一下表
  • 3.更新聚簇索引列的代價很高,因為會強制InnoDB將每個被更新的行移動到新的位置
  • 4.基于聚簇索引的表在插入新行,或者主鍵被更新導致需要移動行的時候,可能面臨"頁分裂(page split)"的問題。當行的主鍵值要求必須將這一行插入到某個已滿的頁中時,存儲引擎會將該頁分裂成兩個頁面來容納該行,這就是一次頁分裂操作。也分裂會導致表占用更多的磁盤空間
  • 5.聚簇索引可能導致全表掃描變慢,尤其是行比較稀疏,或者由于頁分裂導致數據存儲不連續的時候
  • 6.二級索引(非聚簇索引)可能比想象的要更大,因為在二級索引的葉子節點包含了引用行的主鍵列
  • 7.二級索引訪問需要兩次索引查找,而不是一次

最后一點可能讓人有些疑惑,為什么二級索引需要兩次索引查找?答案在于二級索引中保存的"行指針"的實質。要記住,二級索引葉子節點保存的不是指向行的物理位置的指針,而是行的主鍵值。這意味著通過二級索引查找行,存儲引擎需要找到二級索引的葉子節點獲得對應的主鍵值,然后根據這個值去聚簇索引中查找到對應的行。這里做了重復的工作:兩次B-Tree查找而不是一次(順便提一下,并不是所有的非聚簇索引都能做到一次索引查詢就找到行。當行更新的時候可能無法存儲在原來的位置,這會導致表中出現行的碎片花或者移動行并在原位置保存"向前指針"。這兩種情況都會導致查找行時需要更多的工作),對于InnoDB,自適應哈希索引能夠減少這樣的重復工作

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

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

相關文章

【axios】的淺度分析

一、Axios的攔截器能干些什么? Axios攔截器的實現原理主要涉及兩個方面:請求攔截器和響應攔截器,它們分別在請求發送前和響應返回后進行預處理和后處理。 Axios內部維護了兩個數組,一個用于存儲請求攔截器,另一個用于…

數據庫基礎+增刪查改初階

數據庫基礎增刪查改初階 一。數據庫操作 1.概念: 一個mysql服務器上有很多的表,把有關系的表放在一起就構成了一個數據集合,此時稱為“數據庫”,一個mysql1服務器上可以有多個這樣的數據庫 2.創建數據庫: create …

穩住!一招制勝:打造JavaScript防抖函數的終極指南【含代碼示例】

穩住!一招制勝:打造JavaScript防抖函數的終極指南【含代碼示例】 防抖函數:概念與作用基礎實現:案例一簡單防抖函數使用示例 進階功能:案例二 - 立即執行版本性能優化與安全考量實戰技巧與問題排查實際問題與解決方案結…

基于python flask的旅游數據大屏實現,有爬蟲有數據庫

背景 隨著旅游行業的快速發展,數據在旅游決策和規劃中的重要性日益凸顯。基于 Python Flask 的旅游數據大屏實現研究旨在結合爬蟲技術和數據庫存儲,為用戶提供全面、實時的旅游信息展示平臺。 爬蟲技術作為數據采集的重要手段,能夠從各種網…

錯誤記錄:從把項目從Tomcat8.5.37轉到Tomcat10.1.7

錯誤信息:在本地Servlet項目里沒有報錯,但是瀏覽器跳轉該servlet時報錯 型 異常報告 消息 實例化Servlet類[com.wangdao.lx.MyServlet1]異常 描述 服務器遇到一個意外的情況,阻止它完成請求。 例外情況 jakarta.servlet.ServletExceptio…

Generative Action Description Prompts for Skeleton-based Action Recognition

標題:基于骨架的動作識別的生成動作描述提示 源文鏈接:https://openaccess.thecvf.com/content/ICCV2023/papers/Xiang_Generative_Action_Description_Prompts_for_Skeleton-based_Action_Recognition_ICCV_2023_paper.pdfhttps://openaccess.thecvf.c…

解決文件傳輸難題:如何繞過Gitee的100MB上傳限制

引言 在版本控制和代碼托管領域,Gitee作為一個流行的平臺,為用戶提供了便捷的服務。然而,其對單個文件大小設定的100MB限制有時會造成一些不便。 使用云存儲服務 推薦理由: 便捷性:多數云存儲服務如: Dro…

現代操作系統上創建各類鏈接的方法匯總

文章目錄 現代操作系統上創建各類鏈接的方法匯總windows: cmd下的mklink創建鏈接示例 powershell 創建鏈接創建常規文件和目錄創建鏈接 linux shell 創建硬鏈接NAMESYNOPSIS詳細說明常用選項示例 檢查與辨識符號鏈接🎈linux下檢查ls -l 命令file 命令 windows下檢查…

零基礎學習圖生圖

目錄 一、圖生圖是什么二、安裝秋葉整合包2.1 秋葉包安裝2.2 秋葉包拓展安裝:2.3 ckpt配置:2.4 界面常用功能配置: 三、圖生圖基本功能展示3.1 圖生圖的界面3.2 重要的參數設置:3.3 涂鴉功能3.4 局部重繪功能3.5 涂鴉重繪3.6 上傳…

SQL 語言:存儲過程和觸發器

文章目錄 基本概述創建觸發器更改和刪除觸發器總結 基本概述 存儲過程,類似于高階語言的函數或者方法,包含SQL語句序列,是可復用的語句,保存在數據庫中,在服務器中執行。特點是復用,提高了效率&#xff0c…

網絡智能化的發展對仿真環境的需求

1. 網絡智能化背景介紹 1.1 什么是網絡智能化 網絡智能化是指利用人工智能(AI)、機器學習(ML)、優化算法等技術來實現網絡的信息化、自動化和智能化。相對5G、6G、算力網絡等領域,網絡智能化是針對網絡全場景、全要素…

使用C語言openssl庫實現 RSA加密 和 消息驗證

Q:什么是RSA? A:RSA(Rivest-Shamir-Adleman)是一種非對稱加密算法,是最早的一種用于公開密鑰加密和數字簽名的算法。它使用一對公鑰(public key)和私鑰(private key&…

去掉macOS終端命令行前的(base)

macOS在安裝了Anaconda(或miniconda)后,每次打開terminal都會默認打開名為base的虛擬環境。 默認不啟動base conda config --set auto_activate_base false默認啟動base conda config --set auto_activate_base true

IEEE Latex模版踩雷避坑指南

參考文獻 原Latex模版 \begin{thebibliography}{1} \bibliographystyle{IEEEtran}\bibitem{ref1} {\it{Mathematics Into Type}}. American Mathematical Society. [Online]. Available: https://www.ams.org/arc/styleguide/mit-2.pdf\bibitem{ref2} T. W. Chaundy, P. R. Ba…

【前端每日基礎】day27——小程序開發

小程序開發詳細介紹 基本概念 小程序:小程序是一種無需下載安裝即可使用的應用。用戶通過微信搜索或掃描二維碼即可打開小程序。小程序具有觸手可及、用完即走、體驗良好的特點。 組成部分: WXML:用于描述頁面的結構。 WXSS:用于…

2022職稱繼續教育--深入實施新時代人才強國戰略 加快建設世界重要人才中心和創新高地

單選題(共7題,每題5分) 1、()實行職位職級制工資為主。 D、中長線科研重要崗位人員 2、建設世界重要人才中心和創新高地有()個階段目標。 B、三 3、綜合國力競爭說到底是(&#xf…

基于 FastAI 文本遷移學習的情感分類(93%+Accuracy)

前言 系列專欄:【深度學習:算法項目實戰】?? 涉及醫療健康、財經金融、商業零售、食品飲料、運動健身、交通運輸、環境科學、社交媒體以及文本和圖像處理等諸多領域,討論了各種復雜的深度神經網絡思想,如卷積神經網絡、循環神經網絡、生成對…

[vue3后臺管理二]首頁和登錄測試

[vue3后臺管理二]首頁和登錄測試 1 修改main.js import ./assets/main.cssimport { createApp } from vue import App from ./App.vue import router from ./router createApp(App).use(router).mount(#app)2 路由創建 import {createRouter, createWebHistory} from vue-ro…

計算機網絡學習筆記——運輸層(b站)

目錄 一、 運輸層概述 二、運輸層端口號、復用與分用的概念 三、UDP和TCP的對比 四、TCP的流量控制 五、TCP的擁塞控制 六、TCP超時重傳時間的選擇 七、TCP可靠傳輸的實現 八、TCP報文段的首部格式 一、 運輸層概述 物理層、數據鏈路層、網絡層實現了主機到主機的通信…

使用springdoc-openapi-starter-webmvc-ui后訪問swagger-ui/index.html 報錯404

按照官網說明,引入 springdoc-openapi-starter-webmvc-ui后應該就可以直接訪問swagger-ui.html或者swagger-ui/index.html就可以出現swagger頁面了,但是我引入后,訪問提示報錯404. 在我的項目中,有其他依賴間接引入了org.webjars…