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 、 ‘’
用戶自定義變量的類型是動態的,賦值的時候纔會變化。
優化器有時候會把變量優化掉
未定義的變量不會引起語法錯誤,很容易犯錯