MySQ 8.0 推出直方圖,性能大大提升!

来源:https://www.cnblogs.com/javastack/archive/2022/12/06/16955991.html
-Advertisement-
Play Games

作者:LuHengXing 鏈接:http://www.dbapub.cn/2020/09/01/MySQL8.0直方圖/ 查詢優化器負責將SQL查詢轉換為儘可能高效的執行計劃,但隨著數據環境不斷變化,查詢優化器可能無法找到最佳的執行計劃,導致SQL效率低下。造成這種情況的原因是優化器對查詢的數據了 ...


作者:LuHengXing
鏈接:http://www.dbapub.cn/2020/09/01/MySQL8.0直方圖/

查詢優化器負責將SQL查詢轉換為儘可能高效的執行計劃,但隨著數據環境不斷變化,查詢優化器可能無法找到最佳的執行計劃,導致SQL效率低下。造成這種情況的原因是優化器對查詢的數據瞭解的不夠充足,例如:每個表有多少行數據,每列中有多少不同的值,每列的數據分佈情況。

因此MySQL8.0.3推出了直方圖(histogram)功能,直方圖是列的數據分佈的近似值,其向優化器提供更多的統計信息。比如欄位NULL的個數,每個不同值的百分比,最大/最小值等。MySQL的直方圖分為:等寬直方圖和等高直方圖,MySQL會自動分配使用哪種類型的直方圖,無法干預

  • 等寬直方圖:每個bucket保存一個值以及這個值的累計頻率
  • 等高直方圖:每個bucket保存不同值的個數,上下限以及累計頻率

直方圖同時也存在一定的限制條件:

  • 不支持幾何類型以及json類型的列
  • 不支持加密表和臨時表
  • 無法為單列唯一索引的欄位生成直方圖

創建和刪除直方圖

創建語法

ANALYZE TABLE tbl_name UPDATE HISTOGRAM ON col_name [, col_name] WITH N BUCKETS;

創建直方圖時能夠同時為多個列創建直方圖,但必須指定bucket數量,範圍在1-1024之間,預設100。對於bucket數量應該綜合考慮其有多少不同值、數據的傾斜度、精度等,建議從較低的值開始,不符合再依次增加。

刪除語法

ANALYZE TABLE tbl_name DROP HISTOGRAM ON col_name [, col_name];

直方圖信息

MySQL通過字典表column_statistics來保存直方圖的定義,每行記錄對應一個欄位的直方圖,已JSON格式保存。

root@employees 13:49:  select json_pretty(histogram) from information_schema.column_statistics where table_name='employees' and column_name='first_name';;
{
  "buckets": [
    [
      "base64:type254:QWFtZXI=",
      "base64:type254:QWRlbA==",
      0.010176045588684237,
      13
    ],
  "data-type": "string",
  "null-values": 0.0,
  "collation-id": 255,
  "last-updated": "2020-09-09 05:47:32.548874",
  "sampling-rate": 0.163495700259278,
  "histogram-type": "equi-height",
  "number-of-buckets-specified": 100
}

MySQL為employees的first_name欄位分配了等高直方圖,預設為100個bucket。

當生成直方圖時,MySQL會將所有數據都載入到記憶體中,併在記憶體中執行所有工作。如果在大表上生成直方圖,可能會將幾百M的數據讀取到記憶體中的風險,因此我們可以通過參數hitogram_generation_max_mem_size來控制生成直方圖最大允許的記憶體量,當指定記憶體滿足不了所有數據集時就會採用採樣的方式。

root@employees 14:12:  select histogram->>'$."sampling-rate"' from information_schema.column_statistics where table_name='employees' and column_name='first_name';;
+---------------------------------+
| histogram->>'$."sampling-rate"' |
+---------------------------------+
| 0.163495700259278               |
+---------------------------------+

從MySQL8.0.19開始,存儲引擎自身提供了存儲在表中數據的採樣實現,存儲引擎不支持時,MySQL使用預設採樣需要全表掃描,這樣對於大表來說成本太高,採樣實現避免了全表掃描提高採樣性能。

通過INNODB_METRICS計數器可以監視數據頁的採樣情況,這需要提前開啟計數器

root@employees 14:26:  SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE 'sampled%'\G
*************************** 1. row ***************************
 NAME: sampled_pages_read
COUNT: 430
*************************** 2. row ***************************
 NAME: sampled_pages_skipped
COUNT: 456
2 rows in set (0.04 sec)

採樣率的計算公式為:sampled_page_read/(sampled_pages_read + sampled_pages_skipped)

優化案例

複製一張表出來,源表不添加直方圖,新表添加直方圖

root@employees 14:32:  create table employees_like like employees;
Query OK, 0 rows affected (0.03 sec)

root@employees 14:33:  insert into employees_like select * from employees;
Query OK, 300024 rows affected (3.59 sec)
Records: 300024  Duplicates: 0  Warnings: 0

root@employees 14:33:  ANALYZE TABLE employees_like update HISTOGRAM on birth_date,first_name;
+--------------------------+-----------+----------+-------------------------------------------------------+
| Table                    | Op        | Msg_type | Msg_text                                              |
+--------------------------+-----------+----------+-------------------------------------------------------+
| employees.employees_like | histogram | status   | Histogram statistics created for column 'birth_date'. |
| employees.employees_like | histogram | status   | Histogram statistics created for column 'first_name'. |
+--------------------------+-----------+----------+-------------------------------------------------------+

分別在兩張表上查看SQL的執行計劃

root@employees 14:43:  explain format=json select count(*) from employees where (birth_date between '1953-05-01' and '1954-05-01') and first_name like 'A%';
{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "30214.45"
    },
    "table": {
      "table_name": "employees",
      "access_type": "ALL",
      "rows_examined_per_scan": 299822,
      "rows_produced_per_join": 3700,
      "filtered": "1.23",
      "cost_info": {
        "read_cost": "29844.37",
        "eval_cost": "370.08",
        "prefix_cost": "30214.45",
        "data_read_per_join": "520K"
      },
      "used_columns": [
        "birth_date",
        "first_name"
      ],
      "attached_condition": "((`employees`.`employees`.`birth_date` between '1953-05-01' and '1954-05-01') and (`employees`.`employees`.`first_name` like 'A%'))"
    }
  }
}

root@employees 14:45:  explain format=json select count(*) from employees where (birth_date between '1953-05-01' and '1954-05-01') and first_name like 'A%';
{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "18744.56"
    },
    "table": {
      "table_name": "employees",
      "access_type": "range",
      "possible_keys": [
        "idx_birth",
        "idx_first"
      ],
      "key": "idx_first",
      "used_key_parts": [
        "first_name"
      ],
      "key_length": "58",
      "rows_examined_per_scan": 41654,
      "rows_produced_per_join": 6221,
      "filtered": "14.94",
      "index_condition": "(`employees`.`employees`.`first_name` like 'A%')",
      "cost_info": {
        "read_cost": "18122.38",
        "eval_cost": "622.18",
        "prefix_cost": "18744.56",
        "data_read_per_join": "874K"
      },
      "used_columns": [
        "birth_date",
        "first_name"
      ],
      "attached_condition": "(`employees`.`employees`.`birth_date` between '1953-05-01' and '1954-05-01')"
    }
  }
}

可以看出Cost值從30214.45降到了18744.56,掃描行數從299822降到了41654,性能有所提升。

參考資料:

https://dev.mysql.com/doc/refman/8.0/en/analyze-table.html#analyze-table-histogram-statistics-analysis
https://mysqlserverteam.com/histogram-statistics-in-mysql/

近期熱文推薦:

1.1,000+ 道 Java面試題及答案整理(2022最新版)

2.勁爆!Java 協程要來了。。。

3.Spring Boot 2.x 教程,太全了!

4.別再寫滿屏的爆爆爆炸類了,試試裝飾器模式,這才是優雅的方式!!

5.《Java開發手冊(嵩山版)》最新發佈,速速下載!

覺得不錯,別忘了隨手點贊+轉發哦!


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

-Advertisement-
Play Games
更多相關文章
  • 我們是袋鼠雲數棧 UED 團隊,致力於打造優秀的一站式數據中台產品。我們始終保持工匠精神,探索前端道路,為社區積累並傳播經驗價值。 本文作者:正則 作為一名前端開發人員,平時開發中使用最多的就是 Chrome devtools,但可能很多同學像我一樣平時用的最多也就 Console、Elements ...
  • 軟體設計模式(Design pattern),又稱設計模式,是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性、程式的重用性。 ...
  • 摘要:華為雲Solution as Code推出基於Ploto構建自動駕駛平臺解決方案。 本文分享自華為雲社區《基於Ploto構建自動駕駛平臺》,作者:阿米托福 。 2022年6月15日,主題為“因聚而生 為你所能”的華為伙伴暨開發者大會 2022 正式開啟,在自動駕駛專場中,華為雲攜手合作伙伴聯合 ...
  • JSON&Ajax01 JSON 線上文檔 AJAX 線上文檔 1.JSON介紹 JSON指的是JavaScript對象表示法( JavaScript Object Notation),JSON的本質仍然是JavaScript對象 JSON是輕量級的文本數據交互格式,也是前後端進行數據通訊的一種格式 ...
  • pycharm社區版可用於商業項目 pycharm社區版可用於商業項目,來源於官方的回答:Can I use Community Editions of JetBrains IDEs for developing commercial proprietary software? – Licensin ...
  • 歡迎關註專欄【JAVA併發】 前言 開篇一個例子,我看看都有誰會?如果不會的,或者不知道原理的,還是老老實實看完這篇文章吧。 @Slf4j(topic = "c.VolatileTest") public class VolatileTest { static boolean run = true; ...
  • 本文主要介紹面向具體類編程帶來的耦合度問題,再使用面向介面編程進行進一步的解耦並將控制權轉移出去,從而介紹IOC的概念並實現基本使用。 ...
  • 繼Guava Cache之後,我們再來聊一下各方面表現都更佳的Caffeine,看一下其具體使用方式、核心的優化改進點,窺探其青出於藍的秘密所在。 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...