日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL执行计划解析

發(fā)布時間:2023/12/20 数据库 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL执行计划解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

在實際數(shù)據(jù)庫項目開發(fā)中,由于我們不知道實際查詢時數(shù)據(jù)庫里發(fā)生了什么,也不知道數(shù)據(jù)庫是如何掃描表、如何使用索引的,因此,我們能感知到的就只有SQL語句的執(zhí)行時間。尤其在數(shù)據(jù)規(guī)模比較大的場景下,如何寫查詢、優(yōu)化查詢、如何使用索引就顯得很重要了。

那么,問題來了,在查詢前有沒有可能估計下查詢要掃描多少行、使用哪些索引呢?

答案是肯定的。以MySQL為例,MySQL通過explain命令輸出執(zhí)行計劃,對要執(zhí)行的查詢進(jìn)行分析。

什么是執(zhí)行計劃呢?

簡單來說,就是SQL在數(shù)據(jù)庫中執(zhí)行時的表現(xiàn)情況,通常用于SQL性能分析、優(yōu)化等場景。

本文從MySQL的邏輯結(jié)構(gòu)講解,過渡到MySQL的查詢過程,然后給出執(zhí)行計劃的例子并重點介紹執(zhí)行計劃的輸出參數(shù),從而理解為什么我們會選擇文中建議的方案。

MySQL邏輯架構(gòu)

MySQL邏輯架構(gòu)分為三層,如下圖。

  • 客戶端

    • 如,連接處理、授權(quán)認(rèn)證、安全等功能
  • 核心服務(wù)

    • MySQL大多數(shù)核心服務(wù)均在這一層
    • 包括查詢解析、分析、優(yōu)化、緩存、內(nèi)置函數(shù)(如,時間、數(shù)學(xué)、加密等)
    • 所有的跨存儲引擎的功能也在這一層,如,存儲過程、觸發(fā)器、視圖等
  • 存儲引擎

    • 負(fù)責(zé)MySQL中的數(shù)據(jù)存儲和讀取
    • 中間的服務(wù)層通過API與存儲引擎通信,這些API屏蔽了不同存儲引擎間的差異

重點解釋下查詢緩存:對于select語句,在解析查詢之前,服務(wù)器會先檢查查詢緩存(Query Cache)。如果命中,服務(wù)器便不再執(zhí)行查詢解析、優(yōu)化和執(zhí)行的過程,而是直接返回緩存中的結(jié)果集。

MySQL查詢過程

如果能搞清楚MySQL是如何優(yōu)化和執(zhí)行查詢的,對優(yōu)化查詢一定會有幫助。很多查詢優(yōu)化實際上就是遵循一些原則讓優(yōu)化器能夠按期望的合理的方式運(yùn)行。

下圖是MySQL執(zhí)行一個查詢的過程。實際上每一步都比想象中的復(fù)雜,尤其優(yōu)化器,更復(fù)雜也更難理解。本文只給予簡單的介紹。

MySQL查詢過程如下:

  • 客戶端將查詢發(fā)送到MySQL服務(wù)器
  • 服務(wù)器先檢查查詢緩存,如果命中,立即返回緩存中的結(jié)果;否則進(jìn)入下一階段
  • 服務(wù)器對SQL進(jìn)行解析、預(yù)處理,再由優(yōu)化器生成對象的執(zhí)行計劃
  • MySQL根據(jù)優(yōu)化器生成的執(zhí)行計劃,調(diào)用存儲引擎API來執(zhí)行查詢
  • 服務(wù)器將結(jié)果返回給客戶端,同時緩存查詢結(jié)果

執(zhí)行計劃

優(yōu)化與執(zhí)行

MySQL會解析查詢,并創(chuàng)建內(nèi)部數(shù)據(jù)結(jié)構(gòu)(解析樹),并對其進(jìn)行各種優(yōu)化,包括重寫查詢、決定表的讀取順序、選擇合適的索引等。

用戶可通過關(guān)鍵字提示(hint)優(yōu)化器,從而影響優(yōu)化器的決策過程。也可以通過通過優(yōu)化器解釋(explain)優(yōu)化過程的各個因素,使用戶知道數(shù)據(jù)庫是如何進(jìn)行優(yōu)化決策的,并提供一個參考基準(zhǔn),便于用戶重構(gòu)查詢和數(shù)據(jù)庫表的schema、修改數(shù)據(jù)庫配置等,使查詢盡可能高效。

例子

看個例子。

mysql> explain select name, nickname, ctime from dt_user where city = 'shanghai' order by name; +----+-------------+------------+-------+--------------------------+---------------+---------+--------+---------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+--------------------------+---------------+---------+--------+---------+-----------------------+ | 1 | SIMPLE | dt_user | range | PRIMARY,idx_city_name | idx_city_name | 2945 | NULL | 55183 | Using index condition | +----+-------------+------------+-------+--------------------------+---------------+---------+--------+---------+-----------------------+ 1 row in set (0.00 sec)

這個執(zhí)行計劃給出的信息是,該查詢通過一個簡單的給定范圍的掃描,共掃描55183行,使用index condition條件在dt_user表中篩選出,掃描過程中使用PRIMARY和idx_city_name索引。

輸出參數(shù)

輸出各字段解釋如下。更詳細(xì)的信息請參考https://dev.mysql.com/doc/refman/5.7/en/explain-output.html

  • id

    • select查詢序列號
    • id相同,執(zhí)行順序由上至下;id不同,id值越大優(yōu)先級越高,越先被執(zhí)行
  • select_type
    查詢數(shù)據(jù)的操作類型,有如下

  • table
    顯示該行數(shù)據(jù)是關(guān)于哪張表
  • partitions
    匹配的分區(qū)
  • type
    表的連接類型,其值、性能由高到底排列如下

前5種情況都是理想的索引的情況。通常優(yōu)化至少到range級別,最好能優(yōu)化到ref。

  • possible_keys
    指出 MySQL 使用哪個索引在該表找到行記錄。如果該值為 NULL,說明沒有使用索引,可以建立索引提高性能
  • key
    顯示 MySQL 實際使用的索引。如果為 NULL,則沒有使用索引查詢
  • key_len
    表示索引中使用的字節(jié)數(shù),通過該列計算查詢中使用的索引的長度。在不損失精確性的情況下,長度越短越好顯示的是索引字段的最大長度,并非實際使用長度
  • ref
    顯示該表的索引字段關(guān)聯(lián)了哪張表的哪個字段
  • rows
    根據(jù)表統(tǒng)計信息及選用情況,大致估算出找到所需的記錄或所需讀取的行數(shù),數(shù)值越小越好
  • filtered
    返回結(jié)果的行數(shù)占讀取行數(shù)的百分比,值越大越好
  • extra
    包含不適合在其他列中顯示但十分重要的額外信息。常見的值如下

小結(jié)

數(shù)據(jù)庫性能優(yōu)化很多,本文只簡單了介紹MySQL邏輯結(jié)構(gòu)、查詢過程和執(zhí)行計劃參數(shù)。根據(jù)執(zhí)行計劃輸出的索引使用情況、掃描的行數(shù)可以預(yù)估查詢效率,幫助我們重構(gòu)查詢、優(yōu)化表結(jié)構(gòu)或者索引,從而盡可能提供查詢效率。

Reference

    • 《高性能MySQL》
    • https://juejin.im/post/59d83f1651882545eb54fc7e
    • https://blog.csdn.net/chenshun123/article/details/79677037
    • https://yq.aliyun.com/articles/599674
    • https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
    • https://dev.mysql.com/doc/refman/5.7/en/explain-extended.html
    • https://dev.mysql.com/doc/refman/5.7/en/estimating-performance.html

總結(jié)

以上是生活随笔為你收集整理的MySQL执行计划解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。