2013-05-18 68 views
2

我正在運行一個CMS,但這沒有任何關係。對MySQL服務器的更新很慢

我有一個簡單的查詢是:

UPDATE e107_online SET `online_location` = 'http://page.com/something.php?', `online_pagecount` = 133 WHERE `online_ip` = '175.44.*.*' AND `online_user_id` = '0' LIMIT 1; 

但是從我的網站支持報道了同樣的查詢給出:

[email protected]: cosyclim_website[cosyclim_website] @ localhost [] 

Thread_id: 7493739 Schema: cosyclim_website 

Query_time: 12.883518 Lock_time: 0.000028 Rows_sent: 0 Rows_examined: 0 Rows_affected: 1 Rows_read: 1 

它採用12(幾乎13)秒的簡單更新查詢?有什麼辦法可以優化它嗎?如果我通過PhpMyAdmin運行它需要0.0003s。

表:

CREATE TABLE IF NOT EXISTS `e107_online` (
    `online_timestamp` int(10) unsigned NOT NULL default '0', 
    `online_flag` tinyint(3) unsigned NOT NULL default '0', 
    `online_user_id` varchar(100) NOT NULL default '', 
    `online_ip` varchar(15) NOT NULL default '', 
    `online_location` varchar(255) NOT NULL default '', 
    `online_pagecount` tinyint(3) unsigned NOT NULL default '0', 
    `online_active` int(10) unsigned NOT NULL default '0', 
    KEY `online_ip` (`online_ip`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 
+0

您確定該網站已連接到PhpMyAdmin所在的同一個數據庫? – Wiktor

+0

是的,我使用共享主機和只有1個數據庫,因爲我的網站是一個小的。 – Nikola

+0

@Nikola您是在現場主機上還是在本地機器上運行phpMyAdmin?請確保告訴我 – itsols

回答

3

您的查詢更新符合特定條件的一行:

UPDATE e107_online 
    SET `online_location` = 'http://page.com/something.php?', `online_pagecount` = 133 
    WHERE `online_ip` = '175.44.*.*' AND `online_user_id` = '0' 
    LIMIT 1; 

既然你有IP地址,我猜,這表是相當大的。數百萬和數百萬行。更新可能需要很長時間的原因有很多 - 例如服務器負載,阻塞事務和日誌文件性能。在這種情況下,讓我們假設問題是找到其中一行。你可以用相同的條件做一個select來測試這個,看看需要多長時間。

假設select一直很慢,那麼問題可能可以通過索引來解決。如果表沒有索引 - 或者MySQL不能使用現有索引 - 那麼它需要執行全表掃描。而且,也許匹配的一個記錄在表格的最後。它需要一段時間才能找到它。

我建議在e107_online(online_ip)e107_online(online_user_id, online_ip)上加一個索引來幫助它更快地找到記錄。該索引需要是b-tree索引,如here所解釋的。

使用索引的一個結果是具有最低匹配值的IP可能是所選擇的那個。我不知道這種隨機性的缺乏是否會在你的應用中產生影響。

+0

我在我的文章中添加了表格。我沒有數百萬條記錄,我有<50,因爲我的網站並不是真正的人口。正如我已經回答到@itsols我跑所有打開的頁面是一個查詢: DELETE FROM e107_tmp WHERE tmp_time <1368887690 AND tmp_ip =「數據」 AND tmp_ip =「submitted_link」 這不是我的自己的!系統,這是e107,這是一個免費的CMS,但他們在論壇上的幫助是不是你真的可以依靠的:/ – Nikola

+0

我也會檢查任何類型的轉換。我注意到一個online_user_id ='0'檢查。如果online_user_id是一個數字列,那麼MySQL是否可以將它掃描的每一行從字符串解析爲「整數」?可能是小魚,但可能是低掛的水果... – Brandon

+0

well user_id = 0用於沒有登錄(客人)的人,它從未被鑄造 – Nikola

0

只是這個查詢很慢,或者來自您的網站的查詢通常較慢? phpMyAdmin很可能直接在您的數據庫所在的機器上運行查詢,這意味着網絡延遲實際上是0ms。我會建議添加一個索引,包括WHERE子句中的兩列,但是對於50行來說沒有任何意義。這將會降低到您的網站和數據庫服務器之間的阻塞。

還要確保你沒有做任何愚蠢的事情,就像沒有打開連接池(或不必要地創建大量連接)一樣運行。我已經看到空間不足的連接池會導致與此類似的問題。

+0

那麼我已經要求我的託管服務提供商顯示我爲什麼有這麼大的MySQL cpu時間使用。他們給了我兩個緩慢的查詢 - 這一個和另一個(相同類型,相同表格等)。通常我每頁有大約30-40個查詢(肯定小於60),並且需要(根據CMS的內置時間使用情況:渲染時間:0.1416秒,查詢的0.1159,數據庫查詢:31。 – Nikola