一些能體現個人水平的SQL語句
一些能體現個人水平的SQL語句
作為一名小小的開發人員,剛入門的時候覺得很難,過了一段時間之後,發現很簡單,很快就可以搞定很bug了。然而這並不能說明你就已經很牛掰了,只能說,你不了解其他太多的東西。應該說,數據庫有幾個共同的命令,select , update , insert, replace, delete , truncate, drop,只要你學會了,你就感覺你可以為所欲為了。但是在這裡,我要總結一些體現水平的語句,而這些東西恰好直接體現你個人的水平和經驗問題。
1、show processlist : 查看mysql的進程情況,在網站很慢的時候,你應該要想到是不是有很多死的進程或者很耗時的進程,如果確實是這樣,那你應該結束到一些。 kill 99 .
執行狀態分析:
Sleep狀態通常代表資源未釋放,如果是通過連接池,sleep狀態應該恆定在一定數量范圍內,實戰范例:因前端數據輸出時(特別是輸出到用戶終端)未及時關閉數據庫連接,導致因網絡連接速度產生大量sleep連接,在網速出現異常時,數據庫too many connections掛死 Waiting for net, reading from net, writing to net
偶爾出現無妨,如大量出現,迅速檢查數據庫到前端的網絡連接狀態和流量
案例:因外掛程序,內網數據庫大量讀取,內網使用的百兆交換迅速爆滿,導致大量連接阻塞在waiting for net,數據庫連接過多崩潰Locked狀態,有更新操作鎖定,通常使用innodb可以很好的減少locked狀態的產生,但是切記,更新操作要正確使用索引,即便是低頻次更新操作也不能疏忽。如上影響結果集范例所示。在myisam的時代,locked是很多高並發應用的噩夢。所以mysql官方也開始傾向於推薦innodb。
Copy to tmp table
索引及現有結構無法涵蓋查詢條件,才會建立一個臨時表來滿足查詢要求,產生巨大的恐怖的i/o壓力。很可怕的搜索語句會導致這樣的情況,如果是數據分析,或者半夜的周期數據清理任務,偶爾出現,可以允許。頻繁出現務必優化之。
Copy to tmp table通常與連表查詢有關,建議逐漸習慣不使用連表查詢。
實戰范例:
u 某社區數據庫阻塞,求救,經查,其服務器存在多個數據庫應用和網站,其中一個不常用的小網站數據庫產生了一個恐怖的copy to tmp table操作,導致整個硬盤i/o和cpu壓力超載。Kill掉該操作一切恢復。
Sending data
Sending data並不是發送數據,別被這個名字所欺騙,這是從物理磁盤獲取數據的進程,如果你的影響結果集較多,那麼就需要從不同的磁盤碎片去抽取數據,偶爾出現該狀態連接無礙。回到上面影響結果集的問題,一般而言,如果sending data連接過多,通常是某查詢的影響結果集過大,也就是查詢的索引項不夠優化。
如果出現大量相似的SQL語句出現在show proesslist列表中,並且都處於sending data狀態,優化查詢索引,記住用影響結果集的思路去思考。
Storing result to query cache出現這種狀態,如果頻繁出現,使用setprofiling分析,如果存在資源開銷在SQL整體開銷的比例過大(即便是非常小的開銷,看比例),則說明query cache碎片較多,使用flush query cache可即時清理,也可以做成定時任務
Query cache參數可適當酌情設置。
Freeing items
理論上這玩意不會出現很多。偶爾出現無礙,如果大量出現,內存,硬盤可能已經出現問題。比如硬盤滿或損壞。
i/o壓力過大時,也可能出現Free items執行時間較長的情況。
Sorting for 和Sending data類似,結果集過大,排序條件沒有索引化,需要在內存裡排序,甚至需要創建臨時結構排序。
其他還有很多狀態,遇到了,去查查資料。基本上我們遇到其他狀態的阻塞較少,所以不關心
2、checksum 在邏輯備份時候前後是否可以用於驗證數據一致性;
load data [local] infile $filename INTO TABLE table_name TERMINATED BY ',',從文件導入數據到數據庫中。
指定Windows 路徑名時,使用的是斜線而不是反斜線。如果要用反斜線,必須雙寫。
出於安全的原因,當讀取位於服務器上的文本文件時,文件必須位於數據庫目錄下或者可以被所有用戶讀取。也就是說,當對服務器上的文件執行LOAD DATA INFILE 時,用戶必須獲得FILE 權限。
3、索引: 不必要的索引只會占用空間和時間,建立必要索引,唯一索引,主鍵索引。
4、聯表操作:更新,updatetable1 t1 left join table2 t2 on t1.uid=t2.uid set t1.name=t2.name,t1.desc='xxxx' where t1.date='2015-10-11';刪除:delete t1,t2,t3from table1 t1 left join table2 t2 on t1.uid=t2.uid inner join table3 t3 ont2.uid = t3.uid where t1.date='2015-10-11';事務:set@@autocommit=0;