2011-12-05 61 views
2

我有一個非常簡單的查詢,在我的慢查詢日誌中不斷出現。當它收穫時,它通常會說查詢花了大約3-6秒。以下是查詢:如何提高我簡單的mysql查詢速度

UPDATE company_users 
SET isonline=1, last_logon='2011-12-05 19:37:11', last_message=-1, 
    last_signal=-1, location=-1 
WHERE userid='3546600442XXXXX'; 

我必須使用userid比較,因爲這是我在更新時的信息。

數據庫結構是:

Field Type Null Key Default Extra 
id  int(11) NO PRI \N auto_increment 
userid varchar(20) NO MUL  
version varchar(3) YES  37 
owneruserid int(11) NO MUL 0 
simcard_phonenumber varchar(20) YES  \N 
registration_date date YES  \N 
labelname varchar(20) YES  \N 
isonline smallint(6) YES  0 
last_logon datetime YES  \N 
last_message int(11) YES  0 
last_voltage int(11) YES  0 
last_reboot datetime YES  \N  
connect_mode int(11) YES  1 
scheduleid int(11) YES MUL -1 
location  int(11) YES MUL -1 
img    varchar(50) YES   

我有以下的索引:

company_users 0 PRIMARY 1個ID A 197 \ n \ n BTREE
company_users 1 indx_userid 1的userid A 197 \ n \ n BTREE
company_users 1 indx_location 1個位置A 12 \ n \ n YES BTREE
company_users 1 indx_scheduleid 1 scheduleid A 49 \ n \ n YES BTREE
company_us ers 1 indx_owneruserid 1 owneruserid A 197 \ N \ N BTREE

表中有大約300行。數據庫與我的網站位於同一臺服務器上。這些查詢使用PHP腳本運行。

希望這是足夠的信息來了解我可能做錯了什麼,或者我可以調整我的配置。

更新: 丹尼斯的建議後,我再看看我的慢查詢日誌,並注意到有三個對時間框架記錄的語句。這對他們兩個人的信息這是上面確定的相同類型的更新語句:

Query_time:5 Lock_time:0 Rows_sent:0 Rows_examined:0

Query_time:5 Lock_time:0 Rows_sent: 0 Rows_examined:0

Query_time:4 Lock_time:0 Rows_sent:1 Rows_examined:1

這最後被用於在同一個表中選擇。我對select語句進行了分析(因爲我不知道如何在更新上執行此操作),它顯示:

id select_type表類型possible_keys key key_len ref行Extra1 SIMPLE company_users const indx_imei indx_imei 22 const 1

+2

對於包含300行的表,即使沒有任何索引,查詢也應該執行。但是'user_id'上的索引在未來可能會很有用(你已經擁有它了)。 – newtover

回答

2

有很多索引可以加速選擇語句,但會減慢插入,更新和刪除。我的第一個建議是刪除索引並重新執行查詢以查看時間是否有所改善。

+0

這些索引可以幫助我在此表上與其他表一起使用的連接。我有這個錯誤嗎?我在這種情況下使用的索引是location,scheduleid和owneruserid – dreza

+0

不,你是正確的,當連接表時索引確實有助於提高速度;但是如果你打算做大量的更新/插入/刪除行,我會將索引的數目限制在最低限度。另外如果你可以在你的問題中包含解釋計劃,我相信這會有很大的幫助。如果您不熟悉EXPLAIN,可以在這裏找到更多詳細信息,http://dev.mysql.com/doc/refman/5.5/en/using-explain.html –

2

我會建議,在300個記錄的平板上更新記錄的問題與索引無關。這聽起來像你的插入語句被另一個語句阻塞。它是否只在某些條件下才會變得緩慢或緩慢,這將進一步使阻塞似乎成爲可能的候選者。你真的需要更多的信息。我將調查該表上可能的阻塞選擇,以查看它們是否是罪魁禍首,並且首先查看在查看諸如事務隔離級別和自動提交配置之類的事情之前是否可以優化這些查詢。

如果問題是選擇查詢鎖定,則可以通過運行select查詢而不鎖定來驗證(並可能解決您的問題)。這可以通過

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; 
SELECT * FROM TABLE_NAME ; -- Place your select query here 
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ; 

但是,這種方法有一些健康警告與它相關聯。獲得關於錯誤的更多信息是一個更好的做法,通過儘可能地使其儘可能接近最優而解決違規查詢而不是使用此方法。

我記得這個Coding Horror blog有一些有用的見解。

+0

感謝。它可能看起來像那樣。但是,這些不會顯示在慢速查詢日誌中嗎?是否有任何技術或我可以做的事情,以確定任何封鎖選擇,因爲這聽起來像一個可能的罪魁禍首 – dreza

1

我同意AlexC最有可能的另一種說法是阻止你的UPDATE語句。如果你想確定你的UPDATE沒有被阻塞,你可以使用兩個數據庫。在主數據庫上,您執行UPDATES和INSERTS,而從第一個複製的第二個數據是所有SELECT的發生位置。

或者,您當然可以找出哪些語句實際上阻止了您的查詢並嘗試優化它們。在大量選擇的數據庫中,這可能不容易實現。

+0

謝謝Sascha。不知道目前是否有兩個數據庫是計劃但是它可能是我們未來需要研究的東西,也許 – dreza

+0

不確定您的生產環境如何,但測試天氣的可能方式其他查詢阻止更新將是確保執行更新(ofc :)時沒有其他查詢正在運行。如果數據庫不存在,我只會嘗試確保UPDATE查詢是唯一被執行的,並且它仍然很慢。 –