MySQL Execution Plan--合理利用隱式的業務邏輯

来源:https://www.cnblogs.com/gaogao67/archive/2019/10/11/11654649.html
-Advertisement-
Play Games

問題描述 優化過程中遇到一個SQL: 其執行計劃為: 從執行計劃來看,使用Using index(覆蓋索引)已經是最優的執行計劃,但每次查詢掃描數據較多,影響整體查詢性能。 優化方案 查詢需要使用SUM計算user_value的總和,借用1+1+0+0+0+0+0=1+1=2的例子,進行如下測試: ...


問題描述

優化過程中遇到一個SQL:

SELECT
SUM(user_value)
FROM user_log
WHERE del_flag = 0
AND product_id = 2324
AND user_type = 1;

其執行計劃為:

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user_log
   partitions: NULL
         type: ref
possible_keys: index_sId_ty_vl_ct,IDX_product_id_oth1
          key: IDX_product_id_oth1
      key_len: 12
          ref: const,const,const
         rows: 14884
     filtered: 100.00
        Extra: Using index
1 row in set, 1 warning (0.00 sec

從執行計劃來看,使用Using index(覆蓋索引)已經是最優的執行計劃,但每次查詢掃描數據較多,影響整體查詢性能。

 

優化方案

查詢需要使用SUM計算user_value的總和,借用1+1+0+0+0+0+0=1+1=2的例子,進行如下測試:

SELECT
SUM(CASE WHEN user_value>0 THEN 1 ELSE 0 END) AS count1,
COUNT(1) AS count2
FROM user_log
WHERE del_flag = 0
AND product_id = 2324
AND user_type = 1;

+--------+--------+
| count1 | count2 |
+--------+--------+
|    680 |   8067 |
+--------+--------+

在假設user_value沒有負值的情況下,下麵兩條SQL的結果相同:

##測試SQL1
SELECT
SUM(user_value),
COUNT(1) AS count2
FROM user_log
WHERE del_flag = 0
AND product_id = 2324
AND user_type = 1;

##測試SQL2
SELECT
SUM(user_value)
FROM user_log
WHERE del_flag = 0
AND product_id = 2324
AND user_type = 1
AND user_value>0;

測試SQL1的執行時間為0.00327250,其資源消耗為:

+----------------------+----------+----------+------------+--------------+---------------+-------+
| Status               | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out | Swaps |
+----------------------+----------+----------+------------+--------------+---------------+-------+
| starting             | 0.000066 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| checking permissions | 0.000012 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| Opening tables       | 0.000016 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| init                 | 0.000021 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| System lock          | 0.000015 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| optimizing           | 0.000016 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| statistics           | 0.000127 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| preparing            | 0.000019 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| executing            | 0.000011 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| Sending data         | 0.002867 | 0.002999 |   0.000000 |            0 |             0 |     0 |
| end                  | 0.000012 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| query end            | 0.000013 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| closing tables       | 0.000012 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| freeing items        | 0.000054 | 0.000000 |   0.000000 |            0 |             8 |     0 |
| cleaning up          | 0.000012 | 0.000000 |   0.000000 |            0 |             0 |     0 |
+----------------------+----------+----------+------------+--------------+---------------+-------+

而測試SQL2的執行時間為0.00072325,其資源消耗為:

+----------------------+----------+----------+------------+--------------+---------------+-------+
| Status               | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out | Swaps |
+----------------------+----------+----------+------------+--------------+---------------+-------+
| starting             | 0.000072 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| checking permissions | 0.000013 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| Opening tables       | 0.000016 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| init                 | 0.000021 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| System lock          | 0.000014 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| optimizing           | 0.000020 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| statistics           | 0.000089 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| preparing            | 0.000020 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| executing            | 0.000011 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| Sending data         | 0.000365 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| end                  | 0.000012 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| query end            | 0.000014 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| closing tables       | 0.000012 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| freeing items        | 0.000035 | 0.000000 |   0.000000 |            0 |             0 |     0 |
| cleaning up          | 0.000012 | 0.000000 |   0.000000 |            0 |             0 |     0 |
+----------------------+----------+----------+------------+--------------+---------------+-------+

在Sending data部分,兩者在Durion部分差距約10倍,而測試SQL2在CPU_user部分差距更明顯。

 

總結:

DBA在優化SQL時,除了從數據分佈/索引結構等方面入手外,還需要從業務邏輯方面入手。

 

PS:上面的優化是假設user_value沒有負值,而實際業務邏輯中user_value可能存在負值,因此以上優化純屬於瞎編。


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

-Advertisement-
Play Games
更多相關文章
  • 背景分析 消息隊列這個類型的組件一直是非常重要的組件,當經過兩家企業後我就很堅信這個結論了。隊列這種東西,最廣泛的作用還是在於解耦,寬泛一點的說,它可以將不同部門的工作內容進行有效的整合,基於一個約定好的格式,就可以兩頭互相不幹擾的進行開發。可以說這個生產消費的思想不僅僅適用於程式也適用於非常多的地 ...
  • [20191011]拆分rowid 2.txt--//有了鏈接http://blog.itpub.net/267265/viewspace-2659612/=>[20191011]bash任意進位編碼表.txt --//轉化拆分rowid在bash變得非常容易,自己寫一個腳本看看.--//Rowid ...
  • 使用 Windows 身份驗證方式登錄 出現錯誤 無法連接到 本地伺服器 解決問題: SQL server配置管理器:服務遠程過程調用失敗 https://blog.csdn.net/gfjjggg/article/details/83721445 修改TCP/IP屬性:https://www.cn ...
  • 創建一個只讀用戶user2,只能查詢管理員用戶user1下的表,不能增刪改。 ...
  • mongodb中的全部數據: 查詢結果: 通過嵌入文檔中查詢指定title的數據,然後根據price排序,註意需要排序時將查詢的title也一併作為排序欄位,否則順序會錯亂。 查詢結果: ...
  • 建立索引常用的規則 表的主鍵、外鍵必須有索引; 數據量超過300的表應該有索引; 經常與其他表進行連接的表,在連接欄位上應該建立索引; 經常出現在Where子句中的欄位,特別是大表的欄位,應該建立索引; 索引應該建在選擇性高的欄位上; 索引應該建在小欄位上,對於大的文本欄位甚至超長欄位,不要建索引; ...
  • 1.這個異常是指,用戶向資料庫執行插入數據操作時,某條數據的某個欄位值過長,如果是varchar2類型的,當長度超過2000,--4000(最大值)之間的時候,oracle會自動將該欄位值轉為long型的(-_-||有點坑~),然後插入操作失敗。 2.改完數據類型之後還是報這個錯,原因是:當從dua ...
  • 大數據不是某個專業或一門編程語言,實際上它是一系列技術的組合運用。 有人通過下方的等式給出了大數據的定義。 大數據 = 編程技巧 + 數據結構和演算法 + 分析能力 + 資料庫技能 + 數學 + 機器學習 + NLP + OS + 密碼學 + 並行編程 雖然這個等式看起來很長,需要學習的東西很多,但付 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...