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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql优化之query优化

發(fā)布時間:2025/3/17 数据库 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql优化之query优化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ?主要概述:在 MySQL 中有一個專門負責優(yōu)化 SELECT 語句的優(yōu)化器模塊,這就是我們本節(jié)將要重點分析的 MySQL Optimizer,其主要的功能就是通過計算分析系統(tǒng)中收集的各種統(tǒng)計信息,為客戶端請求的 Query 給出他認為最優(yōu)的執(zhí)行計劃,也就是他認為最優(yōu)的數據檢索方式。當 MySQL Optimizer 接收到從 Query Parser (解析器)送過來的 Query 之后,會根據 MySQLQuery 語句的相應語法對該 Query 進行分解分析的同時,還會做很多其他的計算轉化工作。如常量轉化,無效內容刪除,常量計算等等。所有這些工作都只為了 Optimizer 工作的唯一目的,分析出最優(yōu)的數據檢索方式,也就是我們常說的執(zhí)行計劃。

?原理:

在分析 MySQL Optimizer 的工作原理之前,先了解一下 MySQL 的 Query Tree。MySQL 的 Query Tree

是通過優(yōu)化實現(xiàn) DBXP 的經典數據結構和 Tree 構造器而生成的一個指導完成一個 Query 語句的請求所

需要處理的工作步驟,我們可以簡單的認為就是一個的數據處理流程規(guī)劃,只不過是以一個 Tree 的數據

結構存放而已。通過 Query Tree 我們可以很清楚的知道一個 Query 的完成需要經過哪些步驟的處理,

每一步的數據來源在哪里,處理方式是怎樣的。在整個 DBXP 的 Query Tree 生成過程中,MySQL 使用了

LEX 和 YACC 這兩個功能非常強大的語法(詞法)分析工具。MySQL Query Optimizer 的所有工作都是基

于這個 Query Tree 所進行的。各位讀者朋友如果對 MySQL Query Tree 實現(xiàn)生成的詳細信息比較感興

趣,可以參考 Chales A. Bell 的《Expert MySQL》這本書,里面有比較詳細的介紹。

MySQL Query Optimizer 并不是一個純粹的 CBO(Cost Base Optimizer),而是在 CBO 的基礎上增

加了一個被稱為 Heuristic Optimize(啟發(fā)式優(yōu)化)的功能。也就是說,MySQL Query Optimizer 在優(yōu)

化一個 Query 選擇出他認為的最優(yōu)執(zhí)行計劃的時候,并不一定完全按照系數據庫的元信息和系統(tǒng)統(tǒng)計信

息,而是在此基礎上增加了某些特定的規(guī)則。其實我個人的理解就是在 CBO 的實現(xiàn)中增加了部分

RBO(Rule Base Optimizer)的功能,以確保在某些特別的場景下控制 Query 按照預定的方式生成執(zhí)行

計劃。

當客戶端向 MySQL 請求一條 Query ,到命令解析器模塊完成請求分類區(qū)別出是 SELECT 并轉發(fā)給

Query Optimizer 之后,Query Optimizer 首先會對整條 Query 進行,優(yōu)化處理掉一些常量表達式的預

算,直接換算成常量值。并對 Query 中的查詢條件進行簡化和轉換,如去掉一些無用或者顯而易見的條

件,結構調整等等。然后則是分析 Query 中的 Hint 信息(如果有),看顯示 Hint 信息是否可以完全

確定該 Query 的執(zhí)行計劃。如果沒有 Hint 或者 Hint 信息還不足以完全確定執(zhí)行計劃,則會讀取所涉

及對象的統(tǒng)計信息,根據 Query 進行寫相應的計算分析,然后再得出最后的執(zhí)行計劃。

Query Optimizer 是一個數據庫軟件非常核心的功能,雖然在這里說起來只是簡單的幾句話,但是

在 MySQL 內部,Query Optimizer 實際上是經過了很多復雜的運算分析,才得出最后的執(zhí)行計劃。對于

MySQL Query Optimizer 更多的信息,各位讀者可以通過 MySQL Internal 文檔進行更為全面的了解。

在分析如何優(yōu)化 MySQL Query 之前,我們需要先了解一下 Query 語句優(yōu)化的基本思路和原則。一

般來說,Query 語句的優(yōu)化思路和原則主要提現(xiàn)在以下幾個方面:

1. 優(yōu)化更需要優(yōu)化的 Query;

2. 定位優(yōu)化對象的性能瓶頸;

3. 明確的優(yōu)化目標;

4. 從 Explain 入手;

5. 多使用 profile

6. 永遠用小結果集驅動大的結果集;

7. 盡可能在索引中完成排序;

8. 只取出自己需要的 Columns;

9. 僅僅使用最有效的過濾條件;

10. 盡可能避免復雜的 Join 和子查詢;

上面所列的幾點信息,前面 4 點可以理解為 Query 優(yōu)化的一個基本思路,后面部分則是我們優(yōu)化中

的基本原則。

下面我們先針對 Query 優(yōu)化的基本思路做一些簡單的分析,理解為什么我們的 Query 優(yōu)化到底該

如何進行。

優(yōu)化更需要優(yōu)化的 Query

為什么我們需要優(yōu)化更需要優(yōu)化的 Query?這個地球人都知道的“并不能成為問題的問題”我想就

并不需要我過多解釋吧,哈哈。

那什么樣的 Query 是更需要優(yōu)化呢?對于這個問題我們需要從對整個系統(tǒng)的影響來考慮。什么

Query 的優(yōu)化能給系統(tǒng)整體帶來更大的收益,就更需要優(yōu)化。一般來說,高并發(fā)低消耗(相對)的

Query 對整個系統(tǒng)的影響遠比低并發(fā)高消耗的 Query 大。我們可以通過以下一個非常簡單的案例分析來

充分說明問題。

假設有一個 Query 每小時執(zhí)行 10000 次,每次需要 20 個 IO。另外一個 Query 每小時執(zhí)行 10 次,

每次需要 20000 個 IO。

我們先通過 IO 消耗方面來分析。可以看出,兩個 Query 每小時所消耗的 IO 總數目是一樣的,都是

200000 IO/小時。假設我們優(yōu)化第一個 Query,從 20 個 IO 降低到 18 個 IO,也就是僅僅降低了 2 個 IO,

則我們節(jié)省了 2 * 10000 = 20000 (IO/小時)。而如果希望通過優(yōu)化第二個 Query 達到相同的效果,

我們必須要讓每個 Query 減少 20000 / 10 = 2000 IO。我想大家都會相信讓第一個 Query 節(jié)省 2 個 IO

遠比第二個 Query 節(jié)省 2000 個 IO 來的容易。

其次,如果通過 CPU 方面消耗的比較,原理和上面的完全一樣。只要讓第一個 Query 稍微節(jié)省一

小塊資源,就可以讓整個系統(tǒng)節(jié)省出一大塊資源,尤其是在排序,分組這些對 CPU 消耗比較多的操作中

尤其突出。

最后,我們從對整個系統(tǒng)的影響來分析。一個頻繁執(zhí)行的高并發(fā) Query 的危險性比一個低并發(fā)的

Query 要大很多。當一個低并發(fā)的 Query 走錯執(zhí)行計劃,所帶來的影響主要只是該 Query 的請求者的

體驗會變差,對整體系統(tǒng)的影響并不會特別的突出,之少還屬于可控范圍。但是,如果我們一個高并發(fā)

的 Query 走錯了執(zhí)行計劃,那所帶來的后可很可能就是災難性的,很多時候可能連自救的機會都不給你

就會讓整個系統(tǒng) Crash 掉。曾經我就遇到這樣一個案例,系統(tǒng)中一個并發(fā)度較高的 Query 語句走錯執(zhí)

行計劃,系統(tǒng)頃刻間 Crash,甚至我都還沒有反應過來是怎么回事。當重新啟動數據庫提供服務后,系

統(tǒng)負載立刻直線飆升,甚至都來不及登錄數據庫查看當時有哪些 Active 的線程在執(zhí)行哪些 Query。如

果是遇到一個并發(fā)并不太高的 Query 走錯執(zhí)行計劃,至少我們還可以控制整個系統(tǒng)不至于系統(tǒng)被直接壓

跨,甚至連問題根源都難以抓到。

定位優(yōu)化對象的性能瓶頸

當我們拿到一條需要優(yōu)化的 Query 之后,第一件事情是什么?是反問自己,這條 Query 有什么問

題?我為什么要優(yōu)化他?只有明白了這些問題,我們才知道我們需要做什么,才能夠找到問題的關鍵。

而不能就只是覺得某個 Query 好像有點慢,需要優(yōu)化一下,然后就開始一個一個優(yōu)化方法去輪番嘗試。

這樣很可能整個優(yōu)化過程會消耗大量的人力和時間成本,甚至可能到最后還是得不到一個好的優(yōu)化結

果。這就像看病一樣,醫(yī)生必須要清楚的知道我們病的根源才能對癥下藥。如果只是知道我們什么地方

不舒服,然后就開始通過各種藥物嘗試治療,那這樣所帶來的后果可能就非常嚴重了。

所以,在拿到一條需要優(yōu)化的 Query 之后,我們首先要判斷出這個 Query 的瓶頸到底是 IO 還是

CPU。到底是因為在數據訪問消耗了太多的時間,還是在數據的運算(如分組排序等)方面花費了太多資

源?

一般來說,在 MySQL 5.0 系列版本中,我們可以通過系統(tǒng)自帶的 PROFILING 功能很清楚的找出一個

Query 的瓶頸所在。當然,如果讀者朋友為了使用 MySQL 的某些在 5.1 版本中才有的新特性(如

Partition,EVENT 等)亦或者是比較喜歡嘗試新事務而早早使用的 MySQL 5.1 的預發(fā)布版本,可能就沒

辦法使用這個功能了,因為該功能在 MySQL5.1 系列剛開始的版本中并不支持,不過讓人非常興奮的是該

功能在最新出來的 MySQL 5.1 正式版(5.1.30)又已經提供了。而如果讀者朋友正在使用的 MySQL 是

4.x 版本,那可能就只能通過自行分析 Query 的各個執(zhí)行步驟,找到性能損失最大的地方。

明確的優(yōu)化目標

當我們定為到了一條 Query 的性能瓶頸之后,就需要通過分析該 Query 所完成的功能和 Query 對

系統(tǒng)的整體影響制訂出一個明確的優(yōu)化目標。沒有一個明確的目標,優(yōu)化過程將是一個漫無目的而且低

效的過程,也很難達收到一個理想的效果。尤其是對于一些實現(xiàn)應用中較為重要功能點的 Query 更是如

此。

如何設定優(yōu)化目標?這可能是很多人都非常頭疼的問題,對于我自己也一樣。要設定一個合理的優(yōu)

化目標,不能過于理想也不能放任自由,確實是一件非常頭疼的事情。一般來說,我們首先需要清楚的

了解數據庫目前的整體狀態(tài),同時也要清楚的知道數據庫中與該 Query 相關的數據庫對象的各種信息,

而且還要了解該 Query 在整個應用系統(tǒng)中所實現(xiàn)的功能。了解了數據庫整體狀態(tài),我們就能知道數據庫

所能承受的最大壓力,也就清楚了我們能夠接受的最悲觀情況。把握了該 Query 相關數據庫對象的信

息,我們就應該知道實現(xiàn)該 Query 的消耗最理想情況下需要消耗多少資源,最糟糕又需要消耗多少資

源。最后,通過該 Query 所實現(xiàn)的功能點在整個應用系統(tǒng)中的重要地位,我們可以大概的分析出該

Query 可以占用的系統(tǒng)資源比例,而且我們也能夠知道該 Query 的效率給客戶帶來的體驗影響到底有多

大。

當我們清楚了這些信息之后,我們基本可以得出該 Query 應該滿足的一個性能范圍是怎樣的,這也

就是我們的優(yōu)化目標范圍,然后就是通過尋找相應的優(yōu)化手段來解決問題了。如果該 Query 實現(xiàn)的應用

系統(tǒng)功能比較重要,我們就必須讓目標更偏向于理想值一些,即使在其他某些方面作出一些讓步與犧

牲,比如調整 schema 設計,調整索引組成等,可能都是需要的。而如果該 Query 所實現(xiàn)的是一些并不

是太關鍵的功能,那我們可以讓目標更偏向悲觀值一些,而盡量保證其他更重要的 Query 的性能。這種

時候,即使需要調整商業(yè)需求,減少功能實現(xiàn),也不得不應該作出讓步。

從 Explain 入手

現(xiàn)在,優(yōu)化目標也已經明確了,自然是奧開始動手的時候了。我們的優(yōu)化到底該從何處入手呢?答

案只有一個,從 Explain 開始入手。為什么?因為只有 Explain 才能告訴你,這個 Query 在數據庫中是

以一個什么樣的執(zhí)行計劃來實現(xiàn)的。

但是,有一點我們必須清楚,Explain 只是用來獲取一個 Query 在當前狀態(tài)的數據庫中的執(zhí)行計

劃,在優(yōu)化動手之前,我們比需要根據優(yōu)化目標在自己頭腦中有一個清晰的目標執(zhí)行計劃。只有這樣,

優(yōu)化的目標才有意義。一個優(yōu)秀的 SQL 調優(yōu)人員(或者成為 SQL Performance Tuner),在優(yōu)化任何一

個 SQL 語句之前,都應該在自己頭腦中已經先有一個預定的執(zhí)行計劃,然后通過不斷的調整嘗試,再借

助 Explain 來驗證調整的結果是否滿足自己預定的執(zhí)行計劃。對于不符合預期的執(zhí)行計劃需要不斷分析

Query 的寫法和數據庫對象的信息,繼續(xù)調整嘗試,直至得到預期的結果。

當然,人無完人,并不一定每次自己預設的執(zhí)行計劃都肯定是最優(yōu)的,在不斷調整測試的過程中,

如果發(fā)現(xiàn) MySQL Optimizer 所選擇的執(zhí)行計劃的實際執(zhí)行效果確實比自己預設的要好,我們當然還是應

該選擇使用 MySQL optimizer 所生成的執(zhí)行計劃。

上面的這個優(yōu)化思路,只是給大家指了一個優(yōu)化的基本方向,實際操作還需要讀者朋友不斷的結合

具體應用場景不斷的測試實踐來體會。當然也并不一定所有的情況都非要嚴格遵循這樣一個思路,規(guī)則

是死的,人是活的,只有更合理的方法,沒有最合理的規(guī)則。

在了解了上面這些優(yōu)化的基本思路之后,我們再來看看優(yōu)化的幾個基本原則。

永遠用小結果集驅動大的結果集

很多人喜歡在優(yōu)化 SQL 的時候說用小表驅動大表,個人認為這樣的說法不太嚴謹。為什么?因

為大表經過 WHERE 條件過濾之后所返回的結果集并不一定就比小表所返回的結果集大,可能反而更小。

在這種情況下如果仍然采用小表驅動大表,就會得到相反的性能效果。

其實這樣的結果也非常容易理解,在 MySQL 中的 Join,只有 Nested Loop 一種 Join 方式,也就是

MySQL 的 Join 都是通過嵌套循環(huán)來實現(xiàn)的。驅動結果集越大,所需要循環(huán)的此時就越多,那么被驅動表

的訪問次數自然也就越多,而每次訪問被驅動表,即使需要的邏輯 IO 很少,循環(huán)次數多了,總量自然也

不可能很小,而且每次循環(huán)都不能避免的需要消耗 CPU ,所以 CPU 運算量也會跟著增加。所以,如果

我們僅僅以表的大小來作為驅動表的判斷依據,假若小表過濾后所剩下的結果集比大表多很多,結果就

是需要的嵌套循環(huán)中帶來更多的循環(huán)次數,反之,所需要的循環(huán)次數就會更少,總體 IO 量和 CPU 運算

量也會少。而且,就算是非 Nested Loop 的 Join 算法,如 Oracle 中的 Hash Join,同樣是小結果集

驅動大的結果集是最優(yōu)的選擇。

所以,在優(yōu)化 Join Query 的時候,最基本的原則就是“小結果集驅動大結果集”,通過這個原則

來減少嵌套循環(huán)中的循環(huán)次數,達到減少 IO 總量以及 CPU 運算的次數。

盡可能在索引中完成排序

只取出自己需要的 Columns

任何時候在 Query 中都只取出自己需要的 Columns,尤其是在需要排序的 Query 中。為什么?

對于任何 Query,返回的數據都是需要通過網絡數據包傳回給客戶端,如果取出的 Column 越多,

需要傳輸的數據量自然會越大,不論是從網絡帶寬方面考慮還是從網絡傳輸的緩沖區(qū)來看,都是一個浪

費。

如果是需要排序的 Query 來說,影響就更大了。在 MySQL 中存在兩種排序算法,一種是在

MySQL4.1 之前的老算法,實現(xiàn)方式是先將需要排序的字段和可以直接定位到相關行數據的指針信息取

出,然后在我們所設定的排序區(qū)(通過參數 sort_buffer_size 設定)中進行排序,完成排序之后再次

通過行指針信息取出所需要的 Columns,也就是說這種算法需要訪問兩次數據。第二種排序算法是從

MySQL4.1 版本開始使用的改進算法,一次性將所需要的 Columns 全部取出,在排序區(qū)中進行排序后直

接將數據返回給請求客戶端。改行算法只需要訪問一次數據,減少了大量的隨機 IO,極大的提高了帶有

排序的 Query 語句的效率。但是,這種改進后的排序算法需要一次性取出并緩存的數據比第一種算法

要多很多,如果我們將并不需要的 Columns 也取出來,就會極大的浪費排序過程所需要的內存。在

MySQL4.1 之后的版本中,我們可以通過設置 max_length_for_sort_data 參數大小來控制 MySQL 選擇

第一種排序算法還是第二種排序算法。當所取出的 Columns 的單條記錄總大小

max_length_for_sort_data 設置的大小的時候,MySQL 就會選擇使用第一種排序算法,反之,則會選

擇第二種優(yōu)化后的算法。為了盡可能提高排序性能,我們自然是更希望使用第二種排序算法,所以在

Query 中僅僅取出我們所需要的 Columns 是非常有必要的。

僅僅使用最有效的過濾條件

很多人在優(yōu)化 Query 語句的時候很容易進入一個誤區(qū),那就是覺得 WHERE 子句中的過濾條件越多

越好,實際上這并不是一個非常正確的選擇。其實我們分析 Query 語句的性能優(yōu)劣最關鍵的就是要讓他

選擇一條最佳的數據訪問路徑,如何做到通過訪問最少的數據量完成自己的任務。

為什么說過濾條件多不一定是好事呢?請看下面示例:

需求: 查找某個用戶在所有 group 中所發(fā)的討論 message 基本信息。

場景: 1、知道用戶 ID 和用戶 nick_name

2、信息所在表為 group_message

3、group_message 中存在用戶 ID(user_id)和 nick_name(author)兩個索引

方案一:將用戶 ID 和用戶 nick_name 兩者都作為過濾條件放在 WHERE 子句中來查詢,Query 的執(zhí)行計

劃如下:

sky@localhost : example 11:29:37> EXPLAIN SELECT * FROM group_message

-> WHERE user_id = 1 AND author='1111111111'\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: group_message

type: ref

possible_keys: group_message_author_ind,group_message_uid_ind

key: group_message_author_ind

key_len: 98

ref: const

rows: 1

Extra: Using where

1 row in set (0.00 sec)

方案二:僅僅將用戶 ID 作為過濾條件放在 WHERE 子句中來查詢,Query 的執(zhí)行計劃如下:

sky@localhost : example 11:30:45> EXPLAIN SELECT * FROM group_message

-> WHERE user_id = 1\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: group_message

type: ref

possible_keys: group_message_uid_ind

key: group_message_uid_ind

key_len: 4

ref: const

rows: 1

Extra:

1 row in set (0.00 sec)

方案二:僅將用戶 nick_name 作為過濾條件放在 WHERE 子句中來查詢,Query 的執(zhí)行計劃如下:

sky@localhost : example 11:38:45> EXPLAIN SELECT * FROM group_message

-> WHERE author = '1111111111'\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: group_message

type: ref

possible_keys: group_message_author_ind

key: group_message_author_ind

key_len: 98

ref: const

rows: 1

Extra: Using where

1 row in set (0.00 sec)

初略一看三個執(zhí)行計劃好像都挺好的啊,每一個 Query 的執(zhí)行類型都利用到了索引,而且都是

“ref”類型。可是仔細一分析,就會發(fā)現(xiàn),group_message_uid_ind 索引的索引鍵長度為 4(key_len:

4),由于 user_id 字段類型為 int,所以我們可以判定出 Query Optimizer 給出的這個索引鍵長度是

完全準確的。而 group_message_author_ind 索引的索引鍵長度為 98(key_len: 98),因為 author 字

段定義為 varchar(32) ,而所使用的字符集是 utf8,32 * 3 + 2 = 98。而且,由于 user_id 與

author(來源于 nick_name)全部都是一一對應的,所以同一個 user_id 有哪些記錄,那么所對應的

author 也會有完全相同的記錄。所以,同樣的數據在 group_message_author_ind 索引中所占用的存儲

空間要遠遠大于 group_message_uid_ind 索引所占用的空間。占用空間更大,代表我們訪問該索引所需

要讀取的數據量就會更多。所以,選擇 group_message_uid_ind 的執(zhí)行計劃才是最有的執(zhí)行計劃。也就

是說,上面的方案二才是最有方案,而使用了更多的 WHERE 條件的方案一反而沒有僅僅使用 user_id

一個過濾條件的方案一優(yōu)。

可能有些人會說,那如果將 user_id 和 author 兩者建立聯(lián)合索引呢?告訴你,效果可能比沒有這

個索引的時候更差,因為這個聯(lián)合索引的索引鍵更長,索引占用的空間將會更大。

這個示例并不一定能代表所有場景,僅僅是希望讓大家明白,并不是任何時候都是使用的過濾條件

越多性能會越好。在實際應用場景中,肯定會存在更多更復雜的情形,怎樣使我們的 Query 有一個更優(yōu)

化的執(zhí)行計劃,更高效的性能,還需要靠大家仔細分析各種執(zhí)行計劃的具體差別,才能選擇出更優(yōu)化的

Query。

盡可能避免復雜的 Join 和子查詢

我們都知道,MySQL 在并發(fā)這一塊做的并不是太好,當并發(fā)量太高的時候,系統(tǒng)整體性能可能會急

劇下降,尤其是遇到一些較為復雜的 Query 的時候更是如此。這主要與 MySQL 內部資源的爭用鎖定控

制有關,如讀寫相斥等等。對于 Innodb 存儲引擎由于實現(xiàn)了行級鎖定可能還要稍微好一些,如果使用

的 MyISAM 存儲引擎,并發(fā)一旦較高的時候,性能下降非常明顯。所以,我們的 Query 語句所涉及到的

表越多,所需要鎖定的資源就越多。也就是說,越復雜的 Join 語句,所需要鎖定的資源也就越多,所

阻塞的其他線程也就越多。相反,如果我們將比較復雜的 Query 語句分拆成多個較為簡單的 Query 語

句分步執(zhí)行,每次鎖定的資源也就會少很多,所阻塞的其他線程也要少一些。

可能很多讀者會有疑問,將復雜 Join 語句分拆成多個簡單的 Query 語句之后,那不是我們的網絡

交互就會更多了嗎?網絡延時方面的總體消耗也就更大了啊,完成整個查詢的時間不是反而更長了嗎?

是的,這種情況是可能存在,但也并不是肯定就會如此。我們可以再分析一下,一個復雜的 Join Query

語句在執(zhí)行的時候,所需要鎖定的資源比較多,可能被別人阻塞的概率也就更大,如果是一個簡單的

Query,由于需要鎖定的資源較少,被阻塞的概率也會小很多。所以 較為復雜的 Join Query 也有可能

在執(zhí)行之前被阻塞而浪費更多的時間。而且,我們的數據庫所服務的并不是單單這一個 Query 請求,還

有很多很多其他的請求,在高并發(fā)的系統(tǒng)中,犧牲單個 Query 的短暫響應時間而提高整體處理能力也是

非常值得的。優(yōu)化本身就是一門平衡與取舍的藝術,只有懂得取舍,平衡整體,才能讓系統(tǒng)更優(yōu)。

對于子查詢,可能不需要我多說很多人就明白為什么會不被推薦使用。在 MySQL 中,子查詢的實現(xiàn)

目前還比較差,很難得到一個很好的執(zhí)行計劃,很多時候明明有索引可以利用,可 Query Optimizer 就

是不用。從 MySQL 官方給出的信息說,這一問題將在 MySQL6.0 中得到較好的解決,將會引入

SemiJoin 的執(zhí)行計劃,可 MySQL6.0 離我們投入生產環(huán)境使用恐怕還有很遙遠的一段時間。所以,在

Query 優(yōu)化的過程中,能不用子查詢的時候就盡量不要使用子查詢。

上面這些僅僅只是一些常用的優(yōu)化原則,并不是說在 Query 優(yōu)化中就只需要做到這些原則就可以,

更不是說 Query 優(yōu)化只能通過這些原則來優(yōu)化。在實際優(yōu)化過程中,我們還可能會遇到很多帶有較為復

雜商業(yè)邏輯的場景,具體的優(yōu)化方法就只能根據不同的應用場景來具體分析,逐步調整。其實,最有效

的優(yōu)化,就是不要用,也就是不要實現(xiàn)這個商業(yè)需求。


轉載于:https://blog.51cto.com/jinjiang2009/1340516

總結

以上是生活随笔為你收集整理的mysql优化之query优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。