數據庫優化SQL優化之SELECT優化 ——mysql內部優化策略

數據庫的瓶頸經常出現在查詢 語句中,當出現這樣的問題時,我們一般的步驟是查看是否運用了正確的 索引,

這個可以通過explain sql statement來查看,找到對應的字段,合理的索引將會增加你呃數據的訪問速度,但

任何事情都有一個度,如果索引太多,會在插入時要維護更多的索引,這也將是一個大的開銷,但具體怎樣才

合適呢,歡迎大神來討論,這個我不再行,不過一般一個表中有主鍵活唯一鍵,再弄幾個的話應該不是問題。

1.1、mysql是如何執行where字句的

 這些語句通常很快:

SELECT COUNT(*) FROM tbl_name;

SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;

SELECT MAX(key_part2) FROM tbl_name
  WHERE key_part1=constant;

SELECT ... FROM tbl_name
  ORDER BY key_part1,key_part2,... LIMIT 10;

SELECT ... FROM tbl_name
  ORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10;
但前提是這些訪問的字段部分都有索引,因爲如min(),max(),order by 這些語句會用到排序的,但如果之前已經

建立好了索引,那麼讀的時候就通過二分的方法來 遍歷Btree,這速度很快,如果沒有索引,這個只能全表掃描,

速度會很慢的,對於第一個語句,在MyISAM和MEMORY存儲引擎的表,可以直接讀取這個值,因爲這個有這

兩個存儲引擎有相應的計數器來維護數據,但innodb則必須全表掃描才能得到結果,截圖如下:

mysql> explain select count(*) from b_order\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: b_order
         type: index
possible_keys: NULL
          key: status
      key_len: 1
          ref: NULL
         rows: 274146
        Extra: Using index
1 row in set (0.01 sec)
當使用該語句時,掃描了所有的行,但我們是用主鍵索引的,這個速度還比較快

1.2,mysql內部優化策略

          1,count(*) 這個之前已經說了

          2,mysql和oracle都是採用邊讀數據邊判斷數據,滿足數據就發送到客戶端,滿足sql要求就結束查詢,所以

             謹記一下:如果對你的數據不是要求全部的行,比如只要滿足當前sql的幾行數據,最好加上limit語句,這

             樣會讓數據庫提前結束查詢,少佔內存,少讀取數據,少網絡帶寬傳輸

          3,HAVING語句如果在沒有使用聚合函數如count(), min()等,沒有group by語句時,將合併到where字句中

          4,所有的常量表優先於其他表進行讀取,一個常量表的定義爲:

                     1,一個空表或者只有一行的表

                     2,如果一下表使用where字句時,用到了一個非空主鍵或唯一索引,並且這個搜索的是一個常量表達式

                     3,還有一種情況,就是join的一個表就只有幾行,是否會優先讀(可以試試)

                     如下面的語句:

SELECT * FROM t WHERE primary_key=1;
SELECT * FROM t1,t2
  WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
                    解釋:1,第一個是一個小表,只有一行

                                 2,這個先查他t1,因爲其返回的數據只有一行

             

            5,這裏說一下join的策略:數據庫沒有那麼智能,能一下就能找到好的join順序來執行,他會把所有可能的

                join順序都試一下,調用存儲引擎的api來評估代價,然後選擇最小的代價進行執行,所以,我們寫的表

                的順序,對優化器來說,是沒有關係的

             6,在同時使用group by 和order by時,如果字段都來自同一個表,將優先join該表

             7,對於需要排序的數據,如果你在explain中查看到使用了文件排序,但你確定這個數據集不是很大的話,

                 可以在sql中指定SQL_SMALL_RESULT來使用內存臨時表排序,這樣會快些,方法爲:

select sql_small_result * from table_name;
             8,MySQL有可能查詢結果從索引中獲得,但這個一般都是數值

             9,HAVING語句是最後過濾結果的條件

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