讀高性能MySQL(第4版)筆記11_查詢性能優化(中)

来源:https://www.cnblogs.com/lying7/archive/2023/09/20/17711599.html
-Advertisement-
Play Games

1. MySQL的客戶端/伺服器通信協議 1.1. MySQL的客戶端和伺服器之間的通信協議是“半雙工”的 1.2. 在任何時刻,要麼是由伺服器向客戶端發送數據,要麼是由客戶端向伺服器發送數據,這兩個動作不能同時發生 1.3. 當查詢的語句很長的時候,參數max_allowed_packet就特別重 ...


1. MySQL的客戶端/伺服器通信協議

1.1. MySQL的客戶端和伺服器之間的通信協議是“半雙工”的

1.2. 在任何時刻,要麼是由伺服器向客戶端發送數據,要麼是由客戶端向伺服器發送數據,這兩個動作不能同時發生

1.3. 當查詢的語句很長的時候,參數max_allowed_packet就特別重要了

1.4. 一般的伺服器響應給用戶的數據通常很多,由多個數據包組成

1.5. 當伺服器開始響應客戶端請求時,客戶端必須完整地接收整個返回結果,而不能簡單地只取前面幾條結果,然後讓伺服器停止發送數據

1.5.1. 在必要的時候一定要在查詢中加上LIMIT限制

1.6. 當客戶端從伺服器取數據時,看起來是一個拉數據的過程,但實際上是MySQL在向客戶端推送數據的過程

1.7. MySQL通常需要等所有的數據都已經發送給客戶端才能釋放這條查詢所占用的資源,所以接收全部結果並緩存通常可以減少伺服器的壓力,讓查詢能夠早點結束、早點釋放相應的資源

1.8. 當使用多數連接MySQL的庫函數從MySQL獲取數據時,其結果看起來都像是從MySQL伺服器獲取數據,而實際上都是從這個庫函數的緩存獲取數據

1.9. 如果能夠儘早開始處理這些結果集,就能大大減少記憶體的消耗,在這種情況下可以不使用緩存來記錄結果而是直接處理

1.9.1. 對於伺服器來說,需要查詢完成後才能釋放資源,所以在和客戶端交互的整個過程中,伺服器的資源都是被這個查詢所占用的

1.9.2. 用mysql_unbuffered_query()代替mysql_query(),PHP則不會緩存結果

2. SHOW FULL PROCESSLIST命令

2.1. 該命令返回結果中的Command列,其就表示當前的狀態

2.2. Sleep

2.2.1. 線程正在等待客戶端發送新的請求

2.3. Query

2.3.1. 線程正在執行查詢或者正在將結果發送給客戶端

2.4. Locked

2.4.1. 在MySQL伺服器層,該線程正在等待表鎖

2.5. Analyzing and statistics

2.5.1. 線程正在檢查存儲引擎的統計信息,並優化查詢

2.6. Copying to tmp table [on disk]

2.6.1. 線程正在執行查詢,並且將其結果集複製到一個臨時表中

2.6.2. 麽是在做GROUP BY操作

2.6.3. 要麼是在進行文件排序操作

2.6.4. 或者是在進行UNION操作

2.6.5. “on disk”標記,那表示MySQL正在將一個記憶體臨時表放到磁碟上

2.7. Sorting result

2.7.1. 線程正在對結果集進行排序

3. 導致MySQL優化器選擇錯誤的執行計劃

3.1. 統計信息不准確

3.1.1. MySQL伺服器依賴存儲引擎提供的統計信息來評估成本,但是有的存儲引擎提供的信息是準確的,有的偏差可能非常大

3.2. 成本指標並不完全等同於運行查詢的實際成本

3.3. MySQL的最優可能和你想的最優不一樣

3.3.1. MySQL只是基於其成本模型選擇最優的執行計劃,而有些時候這並不是最快的執行方式

3.4. MySQL從不考慮其他併發執行的查詢,這可能會影響到當前查詢的速度

3.5. MySQL也並不是任何時候都是基於成本的優化

3.5.1. 如果存在全文搜索的MATCH()子句,則在存在FULLTEXT索引的時候就使用全文索引

3.5.2. 即使有時候使用其他索引和WHERE條件可以遠比這種方式要快,MySQL也仍然會使用對應的全文索引

3.6. MySQL不會考慮不受其控制的操作的成本

3.6.1. 執行存儲函數或者用戶自定義函數的成本

4. 優化策略

4.1. 靜態優化

4.1.1. 不依賴於特別的數值

4.1.2. 在第一次完成後就一直有效,即使使用不同的參數重覆執行查詢也不會發生變化

4.1.3. 編譯時優化

4.2. 動態優化

4.2.1. 和查詢的上下文有關

4.2.2. 在每次查詢的時候都重新評估

4.2.3. 運行時優化

5. 優化類型

5.1. 重新定義聯接表的順序

5.1.1. 數據表的聯接並不總是按照在查詢中指定的順序進行

5.2. 將外聯接轉化成內聯接

5.2.1. 並不是所有的OUTER JOIN語句都必須以外聯接的方式執行

5.3. 使用代數等價變換規則

5.4. 優化COUNT()、MIN()和MAX()

5.4.1. 索引和列是否可為空通常可以幫助MySQL優化這類表達式

5.5. 預估並轉化為常數表達式

5.5.1. 當MySQL檢測到一個表達式可以轉化為常數的時候,就會一直把該表達式作為常數進行優化處理

5.6. 覆蓋索引掃描

5.6.1. 當索引中的列包含所有查詢中需要使用的列的時候,MySQL就可以使用索引返回需要的數據,而無須查詢對應的數據行

5.7. 子查詢優化

5.7.1. 將子查詢轉換為一種效率更高的形式,從而減少多個查詢多次對數據進行訪問

5.8. 提前終止查詢

5.8.1. 在發現已經滿足查詢需求的時候,MySQL總是能夠立刻終止查詢

5.8.2. 一個典型的例子就是當使用了LIMIT子句的時候

5.9. 類似這種“不同值/不存在”的優化一般可用於DISTINCT、NOT EXIST()或者LEFT JOIN類型的查詢

5.10. ⑩等值傳播

5.11. ⑾列表IN()的比較

5.11.1. IN()完全等同於多個OR條件的子句,因為這兩者是完全等價的

5.11.2. 在MySQL中這點是不成立的,MySQL將IN()列表中的數據先進行排序,然後通過二分查找的方式來確定列表中的值是否滿足條件,這是一個O(logn)複雜度的操作,等價地轉換成OR查詢的複雜度為O(n),對於IN()列表中有大量取值的時候,MySQL的處理速度將會更快

6. 表和索引的統計信息

6.1. 存儲引擎則給優化器提供對應的統計信息,包括:每個表或者索引有多少個頁面、每個表的每個索引的基數是多少、數據行和索引的長度是多少、索引的分佈信息等

7. 聯接查詢

7.1. MySQL對任何聯接都執行嵌套迴圈聯接操作,即MySQL先在一個表中迴圈取出單條數據,然後再嵌套迴圈到下一個表中尋找匹配的行,依次下去,直到找到所有表中匹配的行為止

7.2. 在MySQL 8.0.20版本之後,已經不再使用基於塊的嵌套迴圈聯接操作,取而代之的是哈希聯接

7.2.1. 這讓聯接操作性能變得更好,特別是當數據集可以全部存儲在記憶體時

7.3. 通常多表聯接的時候,可以有多種不同的聯接順序來獲得相同的執行結果

7.4. 執行計劃

7.4.1. 如果你對某個查詢執行EXPLAIN EXTENDED後,再執行SHOWWARNINGS,就可以看到重構出的查詢

7.5. 讓查詢進行更少的回溯和重讀操作

7.5.1. 可以使用STRAIGHT_JOIN關鍵字重寫查詢,讓優化器按照你認為的最優的聯接順序執行

7.6. n個表的聯接可能有n的階乘種聯接順序

7.6.1. 優化器選擇使用“貪婪”搜索的方式查找“最優”的聯接順序

7.6.2. 當需要聯接的表超過optimizer_search_depth的限制的時候,就會選擇“貪婪”搜索模式了

7.7. 查詢不能重新排序,聯接優化器可以利用這一點通過消除選擇來減小搜索空間


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 有關mmd播放器,網上也有許多非常漂亮的實現,如 pmxeditor、saba、blender_mmd_tools等等。。 首先我想先介紹下我參考實現的倉庫: sselecirPyM/Coocoo3D: Experimental MMD renderer using DX12 and DXR. (g ...
  • 在我們設計軟體的很多地方,都看到需要對錶格數據進行導入和導出的操作,主要是方便客戶進行快速的數據處理和分享的功能,本篇隨筆介紹基於WPF實現DataGrid數據的導入和導出操作。 ...
  • 摘要:本智能化住宅防盜報警系統通過PLC以及組態監控實現了多種功能。系統可以自動控制和手動控制,在家人離開後啟動,在到達家後停止。當家裡沒有人時,系統會模擬有人居住的情況,通過設置燈光變換和排氣扇間斷工作來製造有人的情況。晚上通過設置燈光的變化來模擬生活的場景,白天的時候關閉燈光,晚上的時候打開卧室 ...
  • 一:背景 1. 講故事 前些天有位朋友找到我,說他生產上的程式有記憶體暴漲情況,讓我幫忙看下怎麼回事,最簡單粗暴的方法就是讓朋友在記憶體暴漲的時候抓一個dump下來,看一看大概就知道咋回事了。 二:Windbg 分析 1. 到底是誰吃了記憶體 這個問題說的再多也不為過,一定要看清楚這個程式是如何個性化發展 ...
  • 前言 在構建API項目時,有時出於安全考慮,防止訪問用戶惡意攻擊,希望限制此用戶ip地址的請求次數,減輕拒絕服務攻擊可能性,也稱作限流。接下來,我們就來學習開源庫DotNetRateLimiter 如何輕鬆實現限流。 項目使用配置 安裝Nuget包 在新建立的WebAPI項目中,通過Nuget包管理 ...
  • 因為我本身沒有參與過項目架構,所以為了避免後續的開發過程中項目無序,繁雜。所以在這裡我要給我自己設定一個規範。 後端 目前採用的就是:Net6(長期支持)+倉儲模式(類似三層架構) 雖然現在流行微服務,但我目前還沒法自己完全去做,還得學啊! 目前8的預覽版已經出現,但是得申請,7的話是標準期限支持, ...
  • 可擴展性對於物聯網管理系統的設計和開發非常重要,它直接影響著系統的性能、可靠性和能耗等方面,是評估一個系統優劣的重要因素之一。可擴展性對物聯網管理系統的影響主要體現在以下幾個方面: ...
  • 引言 作為一名後端工程師,使用終端是一種常見的做法,也是你應該學習的技能。許多命令和實用程式可以幫助你在使用 Linux 時更有效地完成任務。 基本 Linux 命令 如果你想使用 Linux 操作系統,學習常用的命令將會大有幫助。本篇將為後端工程師回顧一些基本到高級的 Linux 操作命令。 基礎 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...