SQL的查詢優化

1. 查詢優化器

1.1. SQL語句執行需要經歷的環節

  • 解析階段:語法分析和語義檢查,確保語句正確;
  • 優化階段:通過優化器生成查詢計劃;
  • 執行階段:由執行器根據查詢計劃實際執行操作。

1.2. 查詢優化器

查詢優化器的概念:

查詢優化器的作用是為 SQL 查詢生成最優的執行計劃。其內部通常分為兩個階段:

1. 邏輯優化

  • 基于關系代數進行等價重寫(如謂詞下推、連接重寫、視圖展開);
  • 目的是生成多個邏輯上等價但執行效率不同的候選計劃。

2. 物理優化

  • 為邏輯計劃選擇具體的物理操作(如全表掃描 vs 索引掃描,嵌套循環連接 vs 哈希連接);
  • 通過代價估算模型選出代價最小的執行路徑。

查詢優化器的兩種優化方式:

  1. 第一種是基于規則的優化器RBO,Rule-Based Optimizer),規則就是人們以往的經驗,或者是采用已經被證明是有效的方式。通過在優化器里面嵌入規則,來判斷 SQL 查詢符合哪種規則,就按照相應的規則來制定執行計劃,同時采用啟發式規則去掉明顯不好的存取路徑。
  2. 第二種是基于代價的優化器CBO,Cost-Based Optimizer),這里會根據代價評估模型,計算每條可能的執行計劃的代價,也就是 COST,從中選擇代價最小的作為執行計劃。相比于 RBO 來說,CBO 對數據更敏感,因為它會利用數據表中的統計信息來做判斷,針對不同的數據表,查詢得到的執行計劃可能是不同的,因此制定出來的執行計劃也更符合數據表的實際情況。

RBO 的方式更像是一個出租車老司機,憑借自己的經驗來選擇從 A 到 B 的路徑。而 CBO 更像是手機導航,通過數據驅動,來選擇最佳的執行路徑。

1.3. CBO 的代價估算機制

1. 代價模型

能調整的代價模型的參數:

MySQL 中的COST Model就是優化器用來統計各種步驟的代價模型,MySQL 會引入兩張數據表,里面規定了各種步驟預估的代價(Cost Value) ,我們可以從mysql.server_costmysql.engine_cost這兩張表中獲得這些步驟的代價:

SQL > SELECT * FROM mysql.server_cost


server_cost 數據表是在 server 層統計的代價,具體的參數含義如下:

  1. disk_temptable_create_cost,表示臨時表文件(MyISAM 或 InnoDB)的創建代價,默認值為 20。
  2. disk_temptable_row_cost,表示臨時表文件(MyISAM 或 InnoDB)的行代價,默認值 0.5。
  3. key_compare_cost,表示鍵比較的代價。鍵比較的次數越多,這項的代價就越大,這是一個重要的指標,默認值 0.05。
  4. memory_temptable_create_cost,表示內存中臨時表的創建代價,默認值 1。
  5. memory_temptable_row_cost,表示內存中臨時表的行代價,默認值 0.1。
  6. row_evaluate_cost,統計符合條件的行代價,如果符合條件的行數越多,那么這一項的代價就越大,因此這是個重要的指標,默認值 0.1。

在存儲引擎層都包括了哪些代價:

SQL > SELECT * FROM mysql.engine_cost


engine_cost主要統計了頁加載的代價,一個頁的加載根據頁所在位置的不同,讀取的位置也不同,可以從磁盤 I/O 中獲取,也可以從內存中讀取。因此在engine_cost數據表中對這兩個讀取的代價進行了定義:

  1. io_block_read_cost,從磁盤中讀取一頁數據的代價,默認是 1。
  2. memory_block_read_cost,從內存中讀取一頁數據的代價,默認是 0.25。

通過SQL語句調整以上參數:

MySQL 將這些代價參數以數據表的形式呈現給了我們,我們就可以根據實際情況去修改這些參數。因為隨著硬件的提升,各種硬件的性能對比也可能發生變化,比如針對普通硬盤的情況,可以考慮適當增加io_block_read_cost的數值,這樣就代表從磁盤上讀取一頁數據的成本變高了。當我們執行全表掃描的時候,相比于范圍查詢,成本也會增加很多。

io_block_read_cost參數設置為 2.0,使用下面這條命令:

UPDATE mysql.engine_costSET cost_value = 2.0WHERE cost_name = 'io_block_read_cost';
FLUSH OPTIMIZER_COSTS;


我們對mysql.engine_cost中的io_block_read_cost參數進行了修改,然后使用FLUSH OPTIMIZER_COSTS更新內存,然后再查看engine_cost數據表,發現io_block_read_cost參數中的cost_value已經調整為 2.0。

專門針對某個存儲引擎,比如 InnoDB 存儲引擎設置io_block_read_cost,設置為 2:

INSERT INTO mysql.engine_cost(engine_name, device_type, cost_name, cost_value, last_update, comment)VALUES ('InnoDB', 0, 'io_block_read_cost', 2,CURRENT_TIMESTAMP, 'Using a slower disk for InnoDB');
FLUSH OPTIMIZER_COSTS;

再查看一下mysql.engine_cost數據表:

2. 總代價計算方式

可以簡單地認為,總的執行代價等于 I/O 代價 +CPU 代價。在這里 PAGE FETCH 就是 I/O 代價,也就是頁面加載的代價,包括數據頁和索引頁加載的代價。W*(RSI CALLS) 就是 CPU 代價。W 在這里是個權重因子,表示了 CPU 到 I/O 之間轉化的相關系數,RSI CALLS 代表了 CPU 的代價估算,包括了鍵比較(compare key)以及行估算(row evaluating)的代價。

總代價 = I/O 代價 + CPU 代價 [+ 內存代價 + 遠程訪問代價]
  • I/O 成本:頁的加載,如索引頁和數據頁;
  • CPU 成本:如行過濾、鍵比較等操作;
  • W × RSI Calls:W 是 CPU/I/O 的權重因子,RSI Calls 是邏輯計算量。

2. 使用性能分析工具定位SQL執行慢的原因

2.1. 數據庫服務器的優化步驟

整個流程劃分成了觀察(Show status)和行動(Action)兩個部分。字母 S 的部分代表觀察(會使用相應的分析工具),字母 A 代表的部分是行動(對應分析可以采取的行動)。

2.2. 三種性能分析工具

工具

功能

慢查詢日志

定位慢 SQL 語句

EXPLAIN

分析執行計劃與索引使用情況

SHOW PROFILE

分析執行過程中各步驟的時間開銷

1. 慢查詢日志分析(Slow Query Log)

????????1. 查看是否啟用慢查詢日志:

SHOW VARIABLES LIKE '%slow_query_log%';

? ? ? ? 2. 啟用慢查詢日志:

SET GLOBAL slow_query_log = 'ON';
  1. 查看/設置慢查詢時間閾值:
SHOW VARIABLES LIKE '%long_query_time%';
SET GLOBAL long_query_time = 3;  -- 單位為秒

? ? ? ? 3. 使用 mysqldumpslow 工具分析慢查詢日志:

perl mysqldumpslow.pl -s t -t 2 /路徑/slow.log

參數

含義

-s

排序方式(t:時間,c:次數,r:返回行數)

-t

顯示前幾條

-g

正則匹配(不區分大小寫)

? ? ? ? 4. 使用 EXPLAIN 分析 SQL 執行計劃

示例:

EXPLAIN SELECT ... FROM table JOIN table2 ON ...

常見字段說明:

字段

含義

id

查詢執行順序,越大越早執行

select_type

查詢類型(SIMPLE、PRIMARY、SUBQUERY)

table

正在訪問的表

type

訪問方式(越靠前越好)

key

實際使用的索引

rows

預估掃描行數

Extra

額外信息,如是否使用索引覆蓋、臨時表、排序等

數據表的訪問類型:

  • 效率從低到高依次為 all < index < range < index_merge < ref < eq_ref < const/system。

2. 使用 SHOW PROFILE 分析查詢時間

? ? ? ? 1. 開啟 profiling:

SET profiling = 1;

? ? ? ? 2. 執行要分析的 SQL:

SELECT * FROM ...;

? ? ? ? 3. 查看分析結果:

SHOW PROFILES;
SHOW PROFILE FOR QUERY [query_id];

步驟

說明

SHOW PROFILES

顯示最近查詢的耗時

SHOW PROFILE FOR QUERY N

顯示第 N 條查詢的各階段耗時

解決MySQL中長連接內存占用太大的問題:

  1. 定期斷開長連接。使用一段時間,或者程序里面判斷執行過一個占用內存的大查詢后,斷開連接,之后要查詢再重連。
  2. 如果你用的是 MySQL 5.7 或更新版本,可以在每次執行一個比較大的操作后,通過執行 mysql_reset_connection 來重新初始化連接資源。這個過程不需要重連和重新做權限驗證,但是會將連接恢復到剛剛創建完時的狀態。

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

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

相關文章

結構型設計模式之橋接模式

文章目錄 1. 橋接模式概述2. 模式結構3. 橋接模式的優缺點優點缺點 4. 橋接模式的應用場景5. C#代碼示例5.1 簡單示例 - 形狀與顏色5.2 更復雜的示例 - 跨平臺消息發送系統 6. 橋接模式與其他模式的比較7. 真實世界中的橋接模式應用7.1 數據庫驅動7.2 UI框架中的渲染機制 8. 橋…

SolidWorks建模(U盤)- 多實體建模拆圖案例

這個U盤模型并不是一個多裝配體&#xff0c;它是一個多實體零件&#xff0c;它是在零件模式下創建的這些多實體的零部件。按右鍵解除爆炸就可以裝配到一起&#xff0c;再按右鍵爆炸&#xff0c;就能按照之前移動的位置進行炸開 爆炸視圖直接展示 模型案例和素材或取&#xff08…

計算機組成原理核心剖析:CPU、存儲、I/O 與總線系統全解

引言 在當今數字化時代&#xff0c;計算機已經滲透到我們生活的方方面面&#xff0c;從智能手機到超級計算機&#xff0c;從智能家居到自動駕駛汽車。然而&#xff0c;你是否曾好奇過&#xff0c;這些功能強大的設備內部究竟是如何工作的&#xff1f;是什么讓計算機能夠執行各種…

SystemVerilog—Interface語法(二)

在SystemVerilog中&#xff0c;接口&#xff08;interface&#xff09;是一種封裝信號集合、協議邏輯和通信行為的復合結構。其核心定義內容可分為以下十類&#xff1a; 1. 信號聲明 基礎信號&#xff1a;可定義邏輯&#xff08;logic&#xff09;、線網&#xff08;wire&…

DAY43打卡

浙大疏錦行 kaggle找到一個圖像數據集&#xff0c;用cnn網絡進行訓練并且用grad-cam做可視化 進階&#xff1a;并拆分成多個文件 fruit_cnn_project/ ├─ data/ # 存放數據集&#xff08;需手動創建&#xff0c;后續放入圖片&#xff09; │ ├─ train/ …

[藍橋杯C++ 2024 國 B ] 立定跳遠(二分)

題目描述 在運動會上&#xff0c;小明從數軸的原點開始向正方向立定跳遠。項目設置了 n n n 個檢查點 a 1 , a 2 , ? , a n a_1, a_2, \cdots , a_n a1?,a2?,?,an? 且 a i ≥ a i ? 1 > 0 a_i \ge a_{i?1} > 0 ai?≥ai?1?>0。小明必須先后跳躍到每個檢查…

LINUX530 rsync定時同步 環境配置

rsync定時代碼同步 環境配置 關閉防火墻 selinux systemctl stop firewalld systemctl disable firewalld setenforce 0 vim /etc/selinux/config SELINUXdisable設置主機名 hostnamectl set-hostname code hostnamectl set-hostname backup設置靜態地址 cd /etc/sysconfi…

鴻蒙OSUniApp結合機器學習打造智能圖像分類應用:HarmonyOS實踐指南#三方框架 #Uniapp

UniApp結合機器學習打造智能圖像分類應用&#xff1a;HarmonyOS實踐指南 引言 在移動應用開發領域&#xff0c;圖像分類是一個既經典又充滿挑戰的任務。隨著機器學習技術的發展&#xff0c;我們現在可以在移動端實現高效的圖像分類功能。本文將詳細介紹如何使用UniApp結合Ten…

【Redis】大key問題詳解

目錄 1、什么是大key2、大key的危害【1】阻塞風險【2】網絡阻塞【3】內存不均【4】持久化問題 3、如何發現大key【1】使用內置命令【2】使用memory命令&#xff08;Redis 4.0&#xff09;【3】使用scan命令【4】監控工具 4、解決方案【1】拆分大key【2】使用合適的數據結構【3】…

redis核心知識點

Redis是一種基于內存的數據庫&#xff0c;對數據的讀寫操作都是在內存中完成&#xff0c;因此讀寫速度非常快&#xff0c;常用于緩存&#xff0c;消息隊列、分布式鎖等場景。 Redis 提供了多種數據類型來支持不同的業務場景&#xff0c;比如 String(字符串)、Hash(哈希)、 Lis…

vscode不滿足先決條件問題的解決——vscode的老版本安裝與禁止更新(附安裝包)

目錄 起因 vscode更新設置的關閉 安裝包 結語 起因 由于主包用的系統是centos的&#xff0c;且版本有點老了&#xff0c;再加上vscode現在不支持老版本的&#xff0c;這對主包來說更是雪上加霜啊 但是主包看了網上很多教程&#xff0c;眼花繚亂&#xff0c;好多配置要改&…

如何成為一名優秀的產品經理(自動駕駛)

一、 夯實核心基礎 深入理解智能駕駛技術棧&#xff1a; 感知&#xff1a; 攝像頭、雷達&#xff08;毫米波、激光雷達&#xff09;、超聲波傳感器的工作原理、優缺點、融合策略。了解目標檢測、跟蹤、SLAM等基礎算法概念。 定位&#xff1a; GNSS、IMU、高精地圖、輪速計等定…

【ISAQB大綱解讀】信息隱藏指的是什么

在軟件架構中&#xff0c;信息隱藏&#xff08;Information Hiding&#xff09; 是核心設計原則之一&#xff0c;由 David Parnas 在 1972 年提出。它強調通過限制對模塊內部實現細節的訪問&#xff0c;來降低系統復雜度、提高可維護性和可擴展性。在 ISAQB 的學習目標&#xf…

網頁前端開發(基礎進階2--JS)

前面學習了html與css&#xff0c;接下來學習JS&#xff08;JavaScript與Java無關&#xff09;。 web標準&#xff08;網頁標準&#xff09;分為3個部分&#xff1a; 1.html主要負責網頁的結構&#xff08;頁面的元素和內容&#xff09; 2.css主要負責網頁的表現&#xff08;…

完全移除內聯腳本

說明 日期&#xff1a;2025年5月9日。 內聯腳本給跨站腳本攻擊&#xff08;XSS&#xff09;留了條路。 示例 日期&#xff1a;2025年5月9日。 如下網頁文件a.html&#xff1a; <!-- 內聯腳本塊 --> <script> function handleClick{ alert("Hello")…

[藍橋杯]約瑟夫環

約瑟夫環 題目描述 nn 個人的編號是 1 ~ nn&#xff0c;如果他們依編號按順時針排成一個圓圈&#xff0c;從編號是 1 的人開始順時針報數。 &#xff08;報數是從 1 報起&#xff09;當報到 kk 的時候&#xff0c;這個人就退出游戲圈。下一個人重新從 1 開始報數。 求最后剩…

電子電氣架構 --- 如何應對未來區域式電子電氣(E/E)架構的挑戰?

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

isp中的 ISO代表什么意思

isp中的 ISO代表什么意思 在攝影和圖像信號處理&#xff08;ISP&#xff0c;Image Signal Processor&#xff09;領域&#xff0c;ISO是一個用于衡量相機圖像傳感器對光線敏感度的標準參數。它最初源于膠片攝影時代的 “國際標準化組織&#xff08;International Organization …

第十二節:第五部分:集合框架:Set集合的特點、底層原理、哈希表、去重復原理

Set系列集合特點 哈希值 HashSet集合的底層原理 HashSet集合去重復 代碼 代碼一&#xff1a;整體了解一下Set系列集合的特點 package com.itheima.day20_Collection_set;import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; import java.util.…

邁向分布式智能:解析MCP到A2A的通信范式遷移

智能體與外部世界的橋梁之言&#xff1a; 在深入探討智能體之間的協作機制之前&#xff0c;我們有必要先厘清一個更基礎的問題&#xff1a;**單個智能體如何與外部世界建立連接&#xff1f;** 這就引出了我們此前介紹過的 **MCP&#xff08;Model Context Protocol&…