DBA大牛告訴你,如何讓MySQL語句執行加速?

一打開科技類論壇,最常看到的文章主題就是MySQL性能優化了,爲何要優化呢?mysql

由於:程序員

•數據庫出現瓶頸,系統的吞吐量出現訪問速度慢sql

•隨着應用程序的運行,數據庫的中的數據會愈來愈多,處理時間變長數據庫

•數據讀寫速度緩慢性能優化

就是我們說的「性能問題」,程序員一遇到它老是焦頭爛額!函數

今天我對MySQL優化總結了一些心得,但願在你們以後的工做中能有全部幫助!性能

like 前導符優化

like模糊查詢形如'%AAA%'和'%AAA'將不會使用索引,可是業務上不可避免可能又須要使用到這種形式。優化

一般的方法有兩種:3d

方案一:使用覆蓋索引,即查詢出的列只是用索引就能夠獲取,而無須查詢表記錄,這樣也走了索引;cdn

方案二:使用locate函數或者position函數代替like查詢,如table.field like '%AAA%'能夠改成locate('AAA', table.field) > 0或POSITION('AAA' IN table.field)>0

in 和 exist

若是查詢的兩個表大小至關,那麼用in和exists差異不大。 若是兩個表中一個較小,一個是大表,則子查詢表大的用exists,子查詢表小的用in: 例如:表A(小表),表B(大表)

示例一:

示例二:

not in 和 not exist

若是查詢語句使用了not in 那麼內外表都進行全表掃描,沒有用到索引;而not exist 的子查詢依然能用到表上的索引。因此不管哪一個表大,用not exists都比not in要快!

子查詢優化

1)MySQL 5.6 以前的版本對子查詢處理:不會將查詢的結果集計算出來用做與其餘表作join,outer表每掃描一條數據,子查詢都會被從新執行一遍。

2)MySQL 5.6 對子查詢的處理 :將子查詢的結果集 cache 到臨時表裏,臨時表索引主要用來移除重複記錄,而且隨後也可能用於作join查詢,這種技術在 5.6 中叫作物化的子查詢,物化子查詢能夠看到select_type字段爲subquery,而在 5.5 裏爲DEPENDENT SUBQUERY。

3)子查詢通常均可以改爲表的關聯查詢,子查詢會有臨時表的建立、銷燬,效率低下。

straight_join

mysql hint:mysql 優化器在處理多表的關聯的時候,頗有可能會選擇錯誤的驅動表進行關聯,致使了關聯次數的增長,從而使得sql語句執行變得很是的緩慢。

這個時候須要有經驗的DBA進行判斷,選擇正確的驅動表,這個時候 straightjoin 就起了做用了,下面咱們來看一看使用straight_join進行優化的案例。

嘗試採用user表作驅動表,使用straight_join強制鏈接順序:

高效分頁

1)傳統分頁

select*fromtablelimit10000,10

2)limit原理

•Limit 10000,10

•偏移量越大則越慢

3)推薦分頁

複雜關聯SQL的優化

一、首先查詢返回的結果集,一般查詢返回的結果集不多,是有優化的空間的。

二、經過查看執行計劃,查看優化器選擇的驅動表,從執行計劃的rows能夠大體反應出問題的所在。

三、搞清各表的關聯關係,查看關聯字段是否有合適的索引。

四、使用straight_join關鍵詞來強制調整驅動表的選擇,對優化的想法進行驗證。

五、若是條件容許,對複雜的SQL進行拆分。儘量越簡單越好。

force index

有時優化器可能因爲統計信息不許確等緣由,沒有選擇最優的執行計劃,能夠人爲改變mysql的執行計劃,例如:

count的優化

按照效率排序的話,count(字段)<count(主鍵id)<count(1)≈count(),因此我建議你,儘可能使用count()。

總結

MySQL 性能優化 最主要是理解 innodb 的索引原理及結構及 SQL 的執行計劃,在不斷累積經驗的基礎上熟能生巧。

相關文章
相關標籤/搜索