MySQL小結及性能優化(查看執行計劃)

邏輯架構圖1 

 

1.Connectors

指的是不同語言中與SQL的交互

2.Management Serveices & Utilities: 

系統管理和控制工具

3.Connection Pool: 連接池

* 管理緩衝用戶連接線程處理等需要緩存的需求。

* 負責監聽對 MySQL Server 的各種請求,接收連接請求,轉發所有連接請求到線程管理模塊。每一個連接上 MySQL Server 的客戶端請求都會被分配(或創建)一個連接線程爲其單獨服務。

* 而連接線程的主要工作就是負責 MySQL Server 與客戶端的通信,接受客戶端的命令請求,傳遞 Server 端的結果信息等。線程管理模塊則負責管理維護這些連接線程。包括線程的創建,線程的 cache 等。

4.SQL Interface: SQL接口

接受用戶的SQL命令,並且返回用戶需要查詢的結果。比如select from就是調用SQL Interface

5.Parser: 解析器

* SQL命令傳遞到解析器的時候會被解析器驗證和解析

主要功能:

a . 將SQL語句進行語義和語法的分析,分解成數據結構,然後按照不同的操作類型進行分類,然後做出針對性的轉發到後續步驟,以後SQL語句的傳遞和處理就是基於這個結構的。

b.  如果在分解構成中遇到錯誤,那麼就說明這個sql語句是不合理的

6.Optimizer: 查詢優化器

* SQL語句在查詢之前會使用查詢優化器對查詢進行優化

* 它使用的是“選取-投影-聯接”策略進行查詢。

     用一個例子就可以理解: select uid,name from user where gender = 1;

     * 這個select 查詢先根據where 語句進行選取,而不是先將表全部查詢出來以後再進行過濾

     * 這個select查詢先根據uid和name進行屬性投影,而不是將屬性全部取出以後再進行過濾

     * 將這兩個查詢條件聯接起來生成最終查詢結果

7.Cache和Buffer: 查詢緩存

他的主要功能是將客戶端提交給MySQL的 select請求的返回結果集 cache 到內存中,與該 query 的一個 hash 值 做一個對應。該 Query 所取數據的基表發生任何數據的變化之後, MySQL 會自動使該 query 的Cache 失效。在讀寫比例非常高的應用系統中, Query Cache 對性能的提高是非常顯著的。當然它對內存的消耗也是非常大的。

如果查詢緩存有命中的查詢結果,查詢語句就可以直接去查詢緩存中取數據。這個緩存機制是由一系列小緩存組成的。比如表緩存,記錄緩存,key緩存,權限緩存等

8.存儲引擎接口

存儲引擎接口模塊可以說是 MySQL 數據庫中最有特色的一點了。目前各種數據庫產品中,基本上只有 MySQL 可以實現其底層數據存儲引擎的插件式管理。這個模塊實際上只是 一個抽象類,但正是因爲它成功地將各種數據處理高度抽象化,才成就了今天 MySQL 可插拔存儲引擎的特色。

     從圖還可以看出,MySQL區別於其他數據庫的最重要的特點就是其插件式的表存儲引擎。MySQL插件式的存儲引擎架構提供了一系列標準的管理和服務支持,這些標準與存儲引擎本身無關,可能是每個數據庫系統本身都必需的,如SQL分析器和優化器等,而存儲引擎是底層物理結構的實現,每個存儲引擎開發者都可以按照自己的意願來進行開發。 

        注意:存儲引擎是基於表的,而不是數據庫

邏輯架構圖2:

小tips: 

select語句中的列(非聚合函數列),必須出現在group by子句中。

group by子句中的列,不一定要出現在select語句中。

聚合函數只能出現select語句中或者having語句中,一定不能出現在where語句中。

where語句中的條件只能是數據庫中已經存在的字段。

 SQL語句的執行順序:

示例SQL:

SELECT * FROM user LEFT JOIN order ON user.id = order.uid

WHERE order.price > 5000

GROUP BY user.name

HAVING count(1) > 8

ORDER BY user.name

LIMIT 0,10

 

 執行順序:

  1. FROM(將最近的兩張表,進行笛卡爾積)---VT1(VT--->virtual table   虛表)
  2. ON(將VT1按照它的條件進行過濾)---VT2
  3. LEFT JOIN(保留左表的記錄)---VT3
  4. WHERE(過濾VT3中的記錄)--VT4…VTn   (根據where的條件個數來看 一個條件產生一個虛表)
  5. GROUP BY(對VT4的記錄進行分組)---VT5
  6. HAVING(對VT5中的記錄進行過濾)---VT6
  7. SELECT(對VT6中的記錄,選取指定的列)--VT7
  8. ORDER BY(對VT7的記錄進行排序)--VC8(遊標)
  9. LIMIT(對排序之後的值進行分頁)  從VC8的開始處選擇指定數量或比例的行返回給客戶端

遊標:是一個對象,對錶進行排序的查詢可返回一個對象,該對象是包含特定的物理順序的。

WHERE條件執行順序(影響性能)

不同數據庫where條件的執行順序不同:

1.MySQL:從左到右的執行WHERE條件

2.Oracle:從右到左的執行 WHERE條件

3.postgreSQL:從左到右的執行WHERE條件

因此:

   寫WHERE條件的時候,優先級高的部分要去編寫過濾力度最大的條件語句

 

性能優化思路:

1、首先需要使用慢查詢功能,去獲取所有查詢時間比較長的SQL語句。

2、使用explain去查看該SQl的執行計劃。

3、使用show profile去查看該SQL執行時的性能問題。

 

1、MySQL的慢查詢日誌功能,默認是關閉的,需要手動開啓

 

1.臨時開啓慢查詢功能

在 MySQL 執行 SQL 語句設置,但是如果重啓 MySQL 的話將失效

set global slow_query_log = ON;

set global long_query_time = 1;

2.永久開啓慢查詢功能

修改/etc/my.cnf配置文件,重啓 MySQL, 這種永久生效.

[mysqld]

slow_query_log = ON

slow_query_log_file = /var/log/mysql/slow.log    MySQL數據庫慢查詢日誌存儲路徑

long_query_time = 1

 

2、查看執行計劃explain

 

參數說明

expain出來的信息有10列,分別是idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra,下面對這些字段進行解釋:

  1. id: SELECT 查詢的標識符. 每個 SELECT 都會自動分配一個唯一的標識符.
  2. select_type: SELECT 查詢的類型.
  3. table: 查詢的是哪個表
  4. partitions: 匹配的分區
  5. type: join 類型
  6. possible_keys: 此次查詢中可能選用的索引
  7. key: 此次查詢中確切使用到的索引.
  8. ref: 哪個字段或常數與 key 一起被使用
  9. rows: 顯示此查詢一共掃描了多少行. 這個是一個估計值.
  10. filtered: 表示此查詢條件所過濾的數據的百分比
  11. extra: 額外的信息

select_type列說明:

  1. SIMPLE, 表示此查詢不包含 UNION 查詢或子查詢
  2. PRIMARY, 表示此查詢是最外層的查詢
  3. UNION, 表示此查詢是 UNION 的第二或隨後的查詢
  4. DEPENDENT UNION, UNION 中的第二個或後面的查詢語句, 取決於外面的查詢
  5. UNION RESULT, UNION 的結果
  6. SUBQUERY, 子查詢中的第一個 SELECT
  7. DEPENDENT SUBQUERY: 子查詢中的第一個 SELECT, 取決於外面的查詢. 即子查詢依賴於外層查詢的結果.

type列說明

通常來說, 不同的 type 類型的性能關係如下:
ALL < index < range ~ index_merge < ref < eq_ref < const < system

類型

含義

system

表只有一行

const

表最多隻有一行匹配,通用用於主鍵或者唯一索引比較時

eq_ref

每次與之前的表合併行都只在該表讀取一行,這是除了system,const之外最好的一種,特點是使用=,而且索引的所有部分都參與join且索引是主鍵或非空唯一鍵的索引

ref

如果每次只匹配少數行,那就是比較好的一種,使用=或<=>,可以是左覆蓋索引或非主鍵或非唯一鍵

fulltext

全文搜索

ref_or_null

與ref類似,但包括NULL

index_merge

表示出現了索引合併優化(包括交集,並集以及交集之間的並集),但不包括跨表和全文索引。

這個比較複雜,目前的理解是合併單表的範圍索引掃描(如果成本估算比普通的range要更優的話

unique_subquery

在in子查詢中,就是value in (select...)把形如“select unique_key_column”的子查詢替換。

PS:所以不一定in子句中使用子查詢就是低效的!

index_subquery 

同上,但把形如”select non_unique_key_column“的子查詢替換

range 

常數值的範圍

index

a.當查詢是索引覆蓋的,即所有數據均可從索引樹獲取的時候(Extra中有Using Index);

b.以索引順序從索引中查找數據行的全表掃描(無 Using Index);

c.如果Extra中Using Index與Using Where同時出現的話,則是利用索引查找鍵值的意思;

d.如單獨出現,則是用讀索引來代替讀行,但不用於查找

all

全表掃描

 

3、MySQL性能分析語句show profile

 

  1. Query Profiler是MYSQL自帶的一種query診斷分析工具,通過它可以分析出一條SQL語句的性能瓶頸在什麼地方。
  2. 通常我們是使用的explain,以及slow query log都無法做到精確分析,但是Query Profiler卻可以定位出一條SQL語句執行的各種資源消耗情況,比如CPU,IO等,以及該SQL執行所耗費的時間等。不過該工具只有在MYSQL 5.0.37以及以上版本中才有實現。
  3. 默認的情況下,MYSQL的該功能沒有打開,需要自己手動啓動

語句使用:

select @@profiling; //結果1表示開啓 0表示關閉(若關閉 可使用set profiling=1開啓)

show variables like ‘%profil%’;

  • 通過以上兩個語句均可以查看 當前session是否打開了profile功能.

  1. show profile 和 show profiles 語句可以展示當前會話(退出session後,profiling重置爲0) 中執行語句的資源使用情況.
  2. show profiles :以列表形式顯示最近發送到服務器上執行的語句的資源使用情況.顯示的記錄數由變量:profiling_history_size 控制,默認15條

可以查詢指定語句的執行情況   例如Query_ID=139

 

3.show profile: 展示最近一條語句執行的詳細資源佔用信息,默認顯示 Status和Duration兩列

 

show profile 還可根據 show profiles 列表中的 Query_ID ,選擇顯示某條記錄的性能分析(如上圖的操作)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章