很多時候,我們的程式出現的「效能問題」,其實是我們自己寫的那"坨"**的問題,是自己coding的問題,是mysql的dml語句使用的問題。 以下是我總結的關於mysql dml語句的使用中需要注意的點。
絕大多數情況,是不需要select *
的。一旦使用了這種語句,便會讓優化器無法完成索引覆蓋掃瞄這類優化,而且還會增加額外的i/o、記憶體和cpu的消耗。 當然,使用select *
也並不是全是壞處,合理的使用select *
可以簡化開發,提高相同**的復用性。
有時候會發現某些查詢可能需要讀取幾千行資料,但是僅返回幾條或者很少的結果,可以使用以下方式去優化:
傳統的網際網路系統中,強調網路連線盡量少,資料層盡可能在一次連線中完成盡可能多的工作,防止建立多次鏈結,但是這種想法對於mysql並不適用,mysql從設計上讓連線和斷開都很輕量,在一般伺服器上可以支援每秒超過10萬的查詢。
所以對於有些場景下,可以將乙個大的查詢「分而治之」,切分成小查詢,然後再組合起來。例如以下情況:
注意:雖然mysql建立連線十分輕量,但是這不意味著可以逐條迴圈中查詢然後再拼接,這樣效率依然是非常慢,而且通常是工作中sql優化的點。
這算是一條禁忌吧,很多公司的網際網路產品都杜絕join操作,換成先從一張表中先取出資料id,再從另外一張表中使用where in
查詢的兩次單錶查詢操作。主要是以下幾點原因:
假如非用不可,可以採用以下方式來優化:
mysql的臨時表示沒有任何索引的,使用臨時表一般都意味著效能比較低,因此在對效能要求比較高的場景中,最好不要使用帶有臨時表的操作:
具體是否用到臨時表,可以通過explain
來檢視,檢視extra
列的結果,如果出現using temporary
則需要注意。
count()
函式有一點需要特別注意:它是不統計值為null的字段的!所以:不能指定查詢結果的某一列,來統計結果行數。即count(xx column)
不太好。
如果想要統計結果集,就使用count(*)
,效能也會很好。
盡量別使用子查詢,盡可能的使用關聯來代替
通常我們在分頁的時候,通常使用的是limit 50, 10
這種語句。資料少還不錯,但是當資料偏移量非常大的時候,效能就會出現問題,例如select xx,*** from test_table limit 100000020, 20
。掃瞄了100000020條資料,才返回20條資料。這個時候我們可以用一下兩種方式來優化:
利用主鍵自增id,我們如果知道了分頁的上邊界,以上查詢可以改寫為:select ***, *** from test_table where id between ***xx and ***x
。
limit
和offset
的問題,其實就是offset
的問題,它會導致mysql掃瞄大量不需要的行然後再拋棄掉。如果使用某個標籤記錄上一次所取資料的位置,那麼下次就可以直接從書籤位置開始掃瞄,這樣就可以避免使用offset
。
例如以上查詢可以改為:
第一組資料:``select ***, ***x from test_table order by id desc limit 20;
以下是mysql執行查詢的整個過程,explain
可以檢視圖中標紅部分,
explain
會展示很多欄位和內容,其中的內容往往不好記,使用的時候,可以檢視以下**內容: explain**
MySql優化sql語句效能
一.優化方面 可以從下面2個方面進行優化 1.減少io次數 2.減少cpu計算次數 二.常見sql命令誤區 1.count 1 和count primary key 優於 count 實際上count 計算操作做了優化 2.select a,b from 比 select a,b,c from 可以...
mysql的效能優化 mysql效能優化
檢視安裝指令碼 select version 非互動式超時時間,如jdbc show global variables like wait timeout 互動式超時時間,如資料庫工具 show global variables like interactive timeout show sessi...
mysql效能優化配置總結
看了一些優化mysql運維的一些書籍,在此記錄總結下 進入mysql客戶端輸入以下sql 1 連線設定 show variables like max connection show status like max used connections max used connections max ...