源碼下載網淺析MySQL 查詢優化器SEO優化
導讀:2SEO優化優化器(The Optimizer) 這篇描述MySQL查詢優化器的工作原理。MySQL查詢優化器主要為執行的查詢決斷最有效的路線(routine,走向)。 一公司網站建設個業網站建設公司。
優化器(The Optimizer)
這篇描述MySQL查詢優化器的工作原理。MySQL查詢優化器主要為執行的查詢決斷最有效的路線(routine,走向)。
一。源代碼和概念
這部分討論優化器關鍵概念,術語,及在MySQL源代碼怎么對應的。
1.定義
狹義定義:優化器,就是DBMS為查詢時決斷要往哪種執行路徑的一系列路線。
MySQL是經常調整查詢的路線,所以你得把這篇描述的邏輯和在源代碼里的做比較。為了使比較容易些,這里會包含相關文件和公司網站建設路徑的注解,例如源代碼/sql/sql_select.cc,optimize_cond()函數。
當一個查詢被轉成另一種查詢時,其結果是一樣的,就會發生語句轉化。如下這個查詢
SELECT ... WHERE 5 = a
就會被轉化成為
SELECT ... WHERE a = 5
最明顯的語句轉化是少的,有些語句轉化,是為了更快的執行。
2.優化器源代碼
如下偽代碼顯示了/sql/sql_select.cc中handle_select()函數的邏輯結構。(源代碼/sql/sql_select.cc處理SQL查詢)
handle_select()
mysql_select()
JOIN::prepare()
setup_fields()
JOIN::optimize() /* optimizer is from here ... */
optimize_cond()
opt_sum_query()
make_join_statistics()
get_quick_record_count()
choose_plan()
/* Find the best way to access tables */
/* as specified by the user. */
optimize_straight_join()
best_access_path()
/* Find a (sub-)optimal plan among all or subset */
/* of all possible query plans where the user */
/* controls the exhaustiveness of the search. */
greedy_search()
best_extension_by_limited_search()
best_access_path()
/* Perform an exhaustive search for an optimal plan */
find_best()
make_join_select() /* ... to here */
JOIN::exec()
縮進行顯示了哪個函數調用哪個函數,如handle_select()函數調用mysql_select()函數,mysql_select()函數會調用JOIN::prepare()、JOIN::optimize()、JOIN::exec(),以及類推。mysql_select()函數的第一部分是調用JOIN::prepare(),此函數用來上下文分析、元數據建立和一些語句轉化。查詢優化器函數JOIN::optimize()和其所有優化處理中的子路線。當執行完JOIN::optimize()函數后,JOIN::exec()接管并完成JOIN::optimize()函數優化決斷后的執行工作。
雖然有JOIN字出現,其實查詢優化器的工作會處理所有的查詢類型,不單單JOIN聯接查詢。
二。首要優化
這部分討論服務器執行的最重要優化。
1.優化常數關系
常數等值傳遞
如下的表達式會發生語句轉化:
WHERE column1 = column2 AND column2 = 'x'
這種表達式,眾所周知,如果A=B && B=C => A=C(可等值傳遞),上句表達式轉化后變成:
WHERE column1='x' AND column2='x'
當且僅當,操作符為如下的任何一個,在column1 <操作符> column2條件中就會發生語句轉化:
=, <, >, <=, >=, <>, <=>, LIKE
注意:等值傳遞的轉化,不適合于BETWEEN。可能也不適合于LIKE,這是后話。
常數等值傳遞同樣發生在循環中,前一步傳遞的輸出作為后一步傳遞的輸入。
源代碼見/sql/sql_select.cc,change_cond_ref_to_const()函數。或/sql/sql_select.cc,propagate_cond_constants()函數。
剔除死代碼
總是TRUE的條件會發生語句轉化,如:
WHERE 0=0 AND column1='y'
這種情況下,第一個條件會被剔除,最后為:
column1='y'
源代碼見/sql/sql_select.cc,remove_eq_conds()。
總是FLASE的條件也會發生語句轉化,如:
WHERE (0 = AND s1 = OR s1 = 7
小括號和前兩個條件總是FLASE,最后為:
WHERE s1 = 7
還有一些情況下,當WHERE語句中代表不可能的條件,查詢優化器可能會全部剔除語句,如下:
WHERE (0 = AND s1 = 5)
因為這條件永遠不為TRUE,在EXPLAIN分析中會顯示Impossible WHERE。簡單地說,MySQL會說WHERE條件被優化過。
如果一個字段不能為NULL,優化器會剔除所有不相關的IS NULL的條件,這樣
WHERE not_null_column IS NULL
這種條件總為FLASE情況;且
WHERE not_null_column IS NOT NULL
這種條件總為TRUE情況,所以這種字段查詢的條件也被剔網站建設教程除。這種判斷是很微妙的。舉個例:在一個OUT JOIN外聯接,被定義成NOT NULL字段仍然含有NULL值,優化器就會單獨排除IS NULL條件在這種特殊情況中。
優化器不會檢查所有的Impossible WHERE的條件,因為這方面可能性太多了。例如:
CREATE TABLE Table1 (column1 CHAR(1));
...
SELECT * FROM Table1 WHERE column1 = 'Popgo';
優化器不會剔除這種查詢的條件,即使在CREATE TABLE定義中使之成為不可能的條件。
可合并的常數值
如下表達式會發生語句轉化:
WHERE column1 = 1 + 2
最后為:
WHERE column1 = 3
在之前說的常數等值傳遞 ,優化器很容易將這種查詢語句合并在一起。這操作就簡化了結果。
常數值和常數表
MySQL常數值,有時不單單指在查詢的SQL語句的字面意思上,也可在常數表(constant tables)的內容里。常數表(constant tables)被定義為:
1。無記錄或一條記錄的表
2。表的表達式被WHERE條件約束,而且包含的表達式形式column = "constant",或者表的主鍵的所有字段,或者任何唯一鍵的所有字段(唯一鍵的字段定義為NOT NULL)
例如,Table0表的定義包含:
... PRIMARY KEY (column1,column2)
然后,查詢表達式:
FROM Table0 ... WHERE column1=5 AND column2=7 ...
會返回常數表(constant tables)。更多簡單地,如果Table1表的定義包含:
... unique_not_null_column INT NOT NULL UNIQUE
然后,查詢表達式:
FROM Table1 ... WHERE unique_not_null_column=5
也會返回常數表(constant tables)。
這個規則指一個常數表(constant tables)至多有一條記錄值。MySQL就會優先評估是否為常數表(constant tables),并找出那個值。這樣,MySQL會將這值插入查詢語句。如這個例子:
SELECT Table1.unique_not_null_column, Table2.any_column
FROM Table1, Table2
WHERE Table1.unique_not_null_column = Table2.any_column
AND Table1.unique_not_null_column = 5;
MySQL評估這語句時,首先就會發現,按照常數表(constant tables)的第二點定義,查詢條件為unique_not_null_colu企業網站建設mn的表Table1是一個常數表(constant tables),它就會取得這個值。
如果取值失敗,也就是在表Table1里unique_not_null_column = 沒值,EXPLAIN后結果:
Impossible WHERE noticed after reading const tables
相反,如果取值成功,也就是在表Table1里unique_not_null_column = 為一條記錄值,MySQL會轉化為如下語句:
SELECT 5, Table2.any_column
FROM Table1, Table2
WHERE 5 = Table2.any_column
AND 5 = 5;
事實上,這是一個很好的例子。優化器因前面提到的常數等值傳遞進行一些語句轉化。另外,為什么要先描述常數等值傳遞,因為它在MySQL確認什么是常數表(constant tables)前就先進行了。優化器步驟的順序,有時是有差別。
雖然很多查詢都沒常數表(constant tables)參考。應該牢記,以后無論什么時候,常數constant字被提及,它是指任何一個字面上的值或者一個常數表(constant tables)的內容。相關公司網站建設個業網站建設公司。
聲明: 本文由我的SEOUC技術文章主頁發布于:2023-05-24 ,文章源碼下載網淺析MySQL 查詢優化器SEO優化主要講述下載網,源碼,SQL網站建設源碼以及服務器配置搭建相關技術文章。轉載請保留鏈接: http://www.bifwcx.com/article/seo_7125.html