慢查詢總結

1.COUNT

count的作用 統計值的數量和統計行的數量

值是非空表達式(NOT NULL)

一個常見的錯誤就是在想統計行數的時候,在ount的括號中放入列名,如果想知道結果的行數,應該總是使用COUNT(*),這可以清晰的說明意圖,並且得到好的性能。

2.MYISAM

只有在沒有WHERE條件的時候OUNT(*)纔是最快的,在有條件過濾的時候並不非常快。

3.簡單優化

可以利用MYISAM對COUNT(*)的優化對已經有索引的一小部分做統計。

SELET COUNT(*) FROM WORD.ITY WHERE ID>5;

優化爲下面的語句

SELET (SELET COUNT(*) FROM ITY) - COUNT(*) FROM ITY WHERE ID<=5;

這樣的explain只掃描6行數據

使用一個查詢統計同一列中不同值的數量。

select sum(if(color='blue',1,0)) as blue,sum(if(color='red',1,0)) as red from items;

下面是一個等價查詢

select count(color='blue' or null) as blue,count(color='red' or null) as red from items;

4.優化聯接

1.確保on 或using使用的列上有索引。

通常只需要在聯接中的第2個表上添加索引就可以。

2.確保group by或order by只引用一個表中的列。這樣可以使用索引。

3.謹慎升級mysql

 5.優化子查詢

 對於子查詢,儘可能的使用聯接。

 6.優化group by和distinct

1.主要方式:索引

2.優化group by的策略:臨時表或文件排序分組。

SQL_SMALL_RESULT : 強制使用臨時表

SQL_BIG_RESULT :強制使用文件排序

通常對錶的id進行分組會更加高效

可以使用SQL_MODE參數禁止SELET中使用在group by中出現的列

子查詢創建的臨時表不支持索引

所以要讓子查詢創建的臨時表儘可能的小

3.使用ROLL UP 優化GROUP BY

WITH ROLLUP

最好的方式是將WITH ROLLUP 放在應用程序裏。

注意: Rollup 與 order by 相互排拆

 7.優化limit和offset

LIMIT 和ORDER BY 一塊使用。

如果沒有索引,就使用文件排序。

8.優化SQL_AL_FOUND_ROWS

這個地方很重要

一個技巧:在含有limit的查詢中添加SQL_AL_FOUND_ROWS,這樣就可以知道沒有limit的時候會返回多少行數據。服務器會預測將會發現多少行數據。

但是服務器並不能真正的做到,只是告訴服務器生成結果並丟掉結果中不需要的部分。而不是在得到需要的數據後就立即停止。這個選項代價很高。

一個非常好的設計:

如果每頁有20條結果,那麼應該查詢limit 21行數據,只顯示20條,如果結果中有21行,那麼就會有下一頁。

另一種方式:就是提取並緩存大量數據,比如1000行,然後從緩存中獲取後續頁面的數據。

可以讓程序知道一共有多少數據,少於1000,程序知道有多少頁,如果大於1000,可以顯示找到的結果超過1000個。

這兩種都比重複產生完整的結果效率高。

如果以上兩種都不可以使用,可以使用覆蓋索引,使用單獨的count(*)會更好。

9.優化聯合 union

mysql總是使用臨時表來執行union,無法做更多的優化

重要的是,一定要使用union all,除非真的是需要服務器消除重複的行,

否則mysql會使用distint選項,來確保所有行數據的唯一性。

10.用戶自定義變量

一些需要注意的問題:

會禁止緩存

不能用於文字常量和標識的地方(表名,列名,limit)

和連接有關,不能跨通信使用

如果使用連接池,會引起代碼隔離

mysql 5.0大小寫敏感

不能顯示的聲明類型,最好的方式給變量顯示的一個初始值 0 、  0.0 、 ‘’

用戶自定義變量的類型是動態的,賦值的時候纔會變化。

優化器有時候會把變量優化掉

未定義的變量不會引起語法錯誤,很容易犯錯

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