MySQL之查詢性能優化(三)

查詢性能優化

重構查詢的方式

在優化有問題的查詢時,目標應該是找到一個更優的方法獲得實際需要的記過——而不是一定總是需要從MySQL獲取一模一樣的結果集。有時候,可以將查詢轉換一種寫法讓其返回一樣的結果,但是性能更好。但也可以通過修改應用代碼,用另一種方式完成查詢,最終達到一樣的目的。

一個復雜查詢還是多個簡單查詢

設計查詢的時候一個需要考慮的重要問題是,是否需要將一個復雜的查詢分成多個簡單的查詢,在傳統實現中,總是強調需要數據庫層完成盡可能多的工作,這樣做的邏輯在于以前總是認為網絡通信、查詢解析和優化是一件代價很高的事情。但是這樣的想法對于MySQL并不適用,MySQL從設計上讓連接和斷開連接都很輕量級,在返回一個小的查詢結果方面很高效。現代的網絡速度比以前要快很多,無論是貸款還是延遲。在某些版本的MySQL上,即使在一個通用服務器上,也能夠運行超過10萬的查詢,即使是一個千兆網卡(1000Mbps / 8 bit = 125M/s)也能輕松滿足每秒超過2000次的查詢。所以運行多個小查詢現在已經不是大問題了。MySQL內部每秒能夠掃描內存中上百萬行數據,相比之下,MySQL響應數據給客戶端就慢得多了。在其他條件都相同的時候,適用盡可能少的查詢當然是更好地。但是有時候,將一個大查詢分解為多個小查詢是很有必要的。別害怕這樣做,好好衡量一下這樣做是不是會減少工作量。
不過,在應用設計的時候,如果一個查詢能夠勝任時還寫成多個獨立查詢是不明智的。例如,有些應用對一個數據表做10次獨立的查詢來返回10行數據,每個查詢返回一條結果,查詢10次

切分查詢

有時候對于一個大查詢我們需要"分而治之",將大查詢切分成小查詢,每個查詢功能完全一樣,只完成一小部分,每次只返回一小部分查詢結果。刪除舊的數據就是一個很好的例子。定期地清除大量數據時,如果用一個大的語句一次性完成的話,則可能需要依次鎖住很多數據、占滿整個事務日志、耗盡系統資源、阻塞很多小的但很重要的查詢。將一個大的DELETE語句切分成多個較小的查詢可以盡可能小地影響MySQL性能,同時還可以減少MySQL復制地延遲。例如,我們需要每個月運行一次下面的查詢:

mysql> DELETE FROM message WHERE created < DATE_SUB(NOW(), INTERVAL 3 MONT

那么可以用類似下面的辦法來完成同樣的工作:

rows_affected=0
do {
rows_affected = do_query(
"DELETE FROM message WHERE created < DATE_SUB(NOW(), INTERVAL 3 MONTH)
LIMIT 10000"
)
} while rows_affected > 0

一次性刪除一萬行數據一般來說是一個比較高效而且對服務器影響也是最小的做法(如果是事務型引擎,很多時候小事務能夠更高效),同時,需要注意的是,如果每次刪除數據后,都暫停一會兒再做下一次刪除,這樣也可以將服務器上原本一次性的壓力分散到一個很長的時間段中,就可以大大降低對服務器的影響,還可以大大減少刪除時鎖的持有時間

分階關聯查詢

很多高性能的應用都會對關聯查詢進行分解。簡單地,可以對每一個表進行一次單表查詢,然后將結果在應用程序中進行關聯。例如,下面這個查詢:

mysql> SELECT * FROM tag-> JOIN tag_post ON tag_post.tag_id=tag.id-> JOIN post ON tag_post.post_id=post.id-> WHERE tag.tag = 'mysql';

可以分解成下面這些查詢來代替:

mysql> SELECT * FROM tag WHERE tag = 'mysql';
mysql> SELECT * FROM tag_post WHERE tag_id = 1234;
mysql> SELECT * FROM post WHERE post.id IN (123,456,567,9098,8904);

到底為什么要這樣做呢?乍一看,這樣做并沒有什么好處,原本一條查詢,這里卻變成多條查詢,返回的結果又是一模一樣的。事實上,用分解關聯查詢的方式重構查詢有如下的優勢:

  • 1.讓緩存的效率更高。許多應用程序可以方便地緩存單表查詢對應的結果對象。例如,上面查詢中的tag已經被緩存了,那么應用就可以跳過第一個查詢。再例如,應用中已經緩存了ID為123、567、9098的內容,那么第三個查詢中的IN()中就可以少幾個ID.另外,對MySQL的查詢緩存來說(Query Cache),如果關聯中的某個表發生了變化,那么就無法適用查詢緩存了,而拆分后,如果某個表很少改變,那么基于該表的查詢就可以重復利用查詢緩存結果了
  • 2.將查詢分解后,執行單個查詢可以減少鎖的競爭
  • 3.再在應用層做關聯,可以更容易對數據庫進行拆分,更容易做到高性能和可擴展
  • 4.查詢本身效率也可能會有所提升。這個例子中,使用IN()代替關聯查詢,可以讓MySQL按照ID順序進行查詢,這可能比隨機關聯要更高效。
  • 5.可以減少冗余記錄的查詢。在應用層做關聯查詢,意味著對于某條記錄應用只需要查詢一次,而在數據庫中做關聯查詢,則可能需要重復地訪問一部分數據。從這點看,這樣的重構還可能會減少網絡和內存的消耗
  • 6.更進一步,這樣做相當于在應用中實現了哈希關聯,而不是使用MySQL的嵌套循環關聯。某些場景哈希關聯的效率要高很多。
    在很多場景下,通過重構查詢將關聯放到應用程序中將會更加高效,這樣的場景有很多。比如,當應用能夠方便地緩存單個查詢的結果的時候、當可以將數據分不到不同的MySQL服務器上的時候、當能夠使用IN()的方式代替關聯查詢的時候、當查詢中使用同一個數據表的時候

查詢執行的基礎

在這里插入圖片描述

當希望MySQL能夠以更高效的性能運行查詢時,最好的辦法就是弄清楚MySQL是如何優化和執行查詢的。一旦理解這一點,很多查詢優化工作實際上就是遵循一些原則讓優化器能夠按照預想的合理的方式運行。MySQL執行一個查詢的過程。根據如圖所示,我們可以看到當向MySQL發送一個請求的時候,MySQL到底做了些什么。

  • 1.客戶端發送一條查詢給服務器
  • 2.服務器先檢查查詢緩存,如果命中了緩存,則立刻返回存儲在緩存中的結果。否則進入下一階段
  • 3.服務器端進入SQL解析、預處理,再由優化器生成對應的執行計劃
  • 4.MySQL根據優化器生成的執行計劃,調用存儲引擎的API來執行查詢
  • 5.將結果返回給客戶端

上面的每一步都比想象的復雜,接下來我們會看到在每一個階段查詢處于何種狀態。查詢優化器是其中特別復雜也特別難以理解的部分。還有很多的例外情況,例如,當查詢使用綁定變量后,執行路徑會有所不同

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

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

相關文章

Python魔法之旅-魔法方法(14)

目錄 一、概述 1、定義 2、作用 二、應用場景 1、構造和析構 2、操作符重載 3、字符串和表示 4、容器管理 5、可調用對象 6、上下文管理 7、屬性訪問和描述符 8、迭代器和生成器 9、數值類型 10、復制和序列化 11、自定義元類行為 12、自定義類行為 13、類型檢…

在Debian系統上賦予普通用戶ping 權限

在Debian系統上&#xff0c;普通用戶默認情況下沒有權限使用 ping 命令&#xff0c;因為它需要發送 ICMP 包&#xff0c;這通常需要 root 權限。為了允許普通用戶使用 ping&#xff0c;可以設置 ping 命令的 setuid 位。以下是具體的步驟&#xff1a; 查找 ping 命令的位置&am…

2024年度自貢市社會民生重大科技計劃項目申報要求、時間流程

一、申報要求 申報項目需符合以下申報要求和申報指南要求&#xff0c;申報資料需在“自貢市科技綜合業務服務平臺”中的“自貢市重點科技計劃項目管理系統”上傳。 &#xff08;一&#xff09;項目申報單位要求。 1.項目申報單位包括項目牽頭單位和項目合作單位。 2.多家單…

【Python】pyinstaller打包時添加詳細信息

在要被打包的py文件同級目錄新建version.txt&#xff0c;寫入以下內容 # UTF-8 # # For more details about fixed file info ffi see: # http://msdn.microsoft.com/en-us/library/aa381058.aspx # VSVersionInfo(ffiFixedFileInfo(filevers(1, 4, 0, 5),prodvers(1, 4, 0, 5…

SpringBoot使用RabbitMQ實現延遲隊列

SpringBoot使用RabbitMQ實現延遲隊列 需求和目標名詞解釋實現方式引入依賴添加配置文件配置類死信隊列消費者即時隊列消費者延遲消息發送結果注意 需求和目標 商城系統&#xff0c;用戶下單后若15分鐘內仍未完成支付&#xff0c;則自動取消訂單&#xff0c;若已支付&#xff0c…

重組蛋白的定量定性方法,你了解嗎?

重組蛋白的定量和定性分析是蛋白質工程和生物技術中至關重要的步驟&#xff0c;用于確保蛋白質的表達、純度和功能性符合預期。以下是小編整理的一些常用的方法以及實驗介紹&#xff0c;希望這些方法幫助研究人員詳細了解重組蛋白的特性。 主要的定性方法 1 WB&#xff08;Wes…

AIGC 011-SAM第一個圖像分割大模型-分割一切!

AIGC 011-SAM第一個圖像分割大模型-分割一切&#xff01; 文章目錄 0 論文工作1論文方法2 效果 0 論文工作 這篇論文介紹了 Segment Anything (SA) 項目&#xff0c;這是一個全新的圖像分割任務、模型和數據集。SA 項目是一個具有里程碑意義的工作&#xff0c;它為圖像分割領域…

基于springboot的多媒體素材庫源碼數據庫

基于springboot的多媒體素材庫源碼數據庫 近年來&#xff0c;信息化管理行業的不斷興起&#xff0c;使得人們的日常生活越來越離不開計算機和互聯網技術。首先&#xff0c;根據收集到的用戶需求分析&#xff0c;對設計系統有一個初步的認識與了解&#xff0c;確定多媒體素材庫…

迎七一黨史知識競賽答題怎么做

迎七一黨史知識競賽答題&#xff0c;不僅是對于黨史知識的檢驗&#xff0c;更是對于參賽者學習態度和綜合能力的考量。在參與這類競賽時&#xff0c;我們需要做好充分的準備&#xff0c;掌握一定的答題技巧&#xff0c;才能取得好的成績。 首先&#xff0c;我們要深入了解競賽…

FFmpeg播放器的相關概念【1】

播放器框架 相關術語 ?容器&#xff0f;文件&#xff08;Conainer/File&#xff09;&#xff1a;即特定格式的多媒體文件&#xff0c;比如mp4、flv、mkv等。 ? 媒體流&#xff08;Stream&#xff09;&#xff1a;表示時間軸上的一段連續數據&#xff0c;如一段聲音數據、一段…

UFS Explorer Professional Recovery: 如何從啟用了 mSATA 緩存的 Drobo 設備中恢復數據

天津鴻萌科貿發展有限公司是 UFS Explorer Professional Recovery 數據恢復軟件的授權代理商。 UFS Explorer Professional Recovery 數據恢復軟件提供綜合性的解決方案&#xff0c;用于解決復雜的數據恢復案例&#xff0c;包括那些采用特殊存儲技術的案例&#xff0c;或介質受…

上海亞商投顧:創業板指震蕩收漲 超70家ST股跌停

上海亞商投顧前言&#xff1a;無懼大盤漲跌&#xff0c;解密龍虎榜資金&#xff0c;跟蹤一線游資和機構資金動向&#xff0c;識別短期熱點和強勢個股。 一.市場情緒 滬指昨日震蕩震蕩&#xff0c;創業板指走勢稍強&#xff0c;盤中一度漲超1%&#xff0c;黃白二線分化嚴重。算…

vue ts 導入 @/assets/ 紅色顯示的問題解決

vue ts 導入 /assets/ 紅色顯示的問題解決 一、問題描述 在使用的時候這樣導入會出現如上的錯誤。 在使用的時候&#xff0c;導入的類型也沒有對應的代碼提示&#xff0c;說明導入有問題。 二、解決 在 tsconfig.json 中添加如下內容&#xff1a; {"compilerOptions&…

AI大模型探索之路-實戰篇15: Agent智能數據分析平臺之整合封裝Tools和Memory功能代碼

系列篇章&#x1f4a5; AI大模型探索之路-實戰篇4&#xff1a;深入DB-GPT數據應用開發框架調研 AI大模型探索之路-實戰篇5&#xff1a;探索Open Interpreter開放代碼解釋器調研 AI大模型探索之路-實戰篇6&#xff1a;掌握Function Calling的詳細流程 AI大模型探索之路-實戰篇7…

模式識別判斷題

貝葉斯估計的方法類似于貝葉斯決策&#xff0c;也需要定義損失函數。&#xff08;正確&#xff09; 解釋&#xff1a;貝葉斯估計是一種基于貝葉斯定理的參數估計方法&#xff0c;它在估計參數時考慮了參數的先驗分布。與貝葉斯決策類似&#xff0c;貝葉斯估計也需要定義損失函數…

46.ThreadPoolExcutor接口

線程池狀態 ThreadPoolExcutor使用int高3位來表示線程池狀態&#xff0c;低29位表示線程數量 狀態高三位接收新任務處理阻塞隊列任務說明RUNNING111YYSHUTDOWN000NY不會接收新任務&#xff0c;但會處理阻塞隊列剩余任務&#xff0c;比較溫和&#xff0c;已經提交的任務都會執…

15.1 測試-重要性與testing包

1. 測試的重要性 1.1 單元測試 單元測試是針對一小部分代碼進行獨立地測試。 單元測試的對象通常是單個函數或方法&#xff0c;而要測試的是它在接受給定的輸入后&#xff0c;能否產生符合預期的輸出。 單元測試的作用主要表現在以下兩個方面&#xff1a; 驗證程序的最小…

C++ STL-迭代器函數對象適配器

目錄 一.迭代器 二. 函數對象 三. 適配器 一.迭代器 是一種通用的指針類型&#xff0c;可以用來遍歷 STL 容器中的元素。 具有以下作用和意義&#xff1a; 提供一種通用的方式來訪問容器中的元素。允許對不同類型的容器進行統一的操作。增強了代碼的靈活性和可擴展性。 一…

The Best Toolkit 最好用的工具集

The Best Toolkit 工欲善其事&#xff0c;必先利其器&#xff0c;整理過往工作與生活中遇到的最好的工具軟件 PDF合并等 PDF24 Tools PDF查看器 SumatraPDF 可以使用黑色來查看&#xff0c;相對不傷眼睛&#xff0c;也有電子書相關的閱讀器 Kindle pdf裁邊工具 briss 軟件卸載…

【C++題解】1085 - 尋找雷劈數

問題&#xff1a;1085 - 尋找雷劈數 類型&#xff1a;for循環 題目描述&#xff1a; 把整數 3025 從中剪開分為 30 和 25 兩個數&#xff0c;此時再將這兩數之和平方&#xff0c;計算結果又等于原數。 (3025)(3025)55553025 &#xff0c;這樣的數叫“雷劈數”。 求所有符合這…