2011-04-30 26 views
4

爲了清晰起見,DB中的所有其他表都按預期工作,並在幾分之一秒內加載~2百萬行。只有~600行的表格需要10分鐘才能加載到navcat中。在MySQL中加載一個表的速度很慢

我想不出任何可能的原因。只有4列。其中之一一個大型的文本字段,但我以前使用過大型文本字段,他們從來沒有這麼慢。

運行explain select * from parser_queue我得到

id setect type table  type possible keys key key len ref rows extra 
1 SIMPLE parser_queue ALL -    - -  - 658 - 

的輪廓告訴我,453秒花在「發送數據」 我也是在「狀態」選項卡得到這個。我不明白其中的大部分,但這些數字遠高於我的其他表格。

Bytes_received   31 
Bytes_sent    32265951 
Com_select    1 
Created_tmp_files   16 
Handler_read_rnd_next  659 
Key_read_requests   9018487 
Key_reads     3928 
Key_write_requests  310431 
Key_writes    4290 
Qcache_hits    135077 
Qcache_inserts   14289 
Qcache_lowmem_prunes  4133 
Qcache_queries_in_cache 983 
Questions     1 
Select_scan    1 
Table_locks_immediate  31514 

存儲在文本字段中的數據平均約爲12000個字符。 有一個主要的自動增量int id字段,tinyint狀態字段,text字段和timestamp字段on update current timestamp


OK,我會嘗試兩個答案,但我可以很快先回答以下問題:

上的ID字段主鍵是唯一的關鍵。此表用於排隊,每小時添加/刪除約50條記錄,但我只在昨天創建了它。它會在這麼短的時間內損壞嗎?

它的MyISAM


更多的工作,試圖隔離問題:

repair table什麼也沒做 optimize table什麼也沒做 創建一個臨時表。查詢在臨時表上慢了大約50%。

刪除表並重建它。 SELECT *需要18秒,只需4行

這裏是我用來創建表的SQL:

CREATE TABLE IF NOT EXISTS `parser_queue` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `status` tinyint(4) NOT NULL DEFAULT '1', 
    `data` text NOT NULL, 
    `last_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM; 

更奇怪的是,似乎一切都在我的地方框罰款。緩慢只發生在開發現場。

爲了清楚起見:在dev網站上有超過100個表格,這是只有一個這是很時髦的。


好的我已禁用所有使用此表的cron作業。 SHOW PROCESSLIST不會顯示錶上的任何鎖。

改變發動機InnoDB沒有產生任何顯著改善(86秒VS 94對MyISAM)

任何其他的想法? 。 。 。

在查詢過程中運行SHOW PROCESSLIST揭示它花費大量的時間writing to net

+0

'只有4行18秒,哇!是否有可能其他查詢鎖定表?你有沒有嘗試使用InnoDB而不是MyISAM來表格? – 2011-04-30 19:17:51

+0

您是否嘗試過鎖定(使用Read Lock)表,然後運行SELECT? 'concurrent_insert'變量的設置是什麼? – 2011-04-30 19:25:04

+0

讓我們知道是否將引擎轉換爲InnoDB有助於解決問題。 – Pentium10 2011-04-30 19:41:07

回答

2

如果您懷疑損壞的地方,你可以嘗試兩種(或兩種)操作:

CREATE TABLE temp SELECT * FROM parser_queue; 

這將創建一個新表與上一個「相同」,除了它將被重新創建。另外(或者你已經有了一個副本,也許以後),你可以嘗試:

REPAIR TABLE parser_queue; 

您也可以嘗試優化表;它可能已經被分割,因爲你將它用作隊列。

OPTIMIZE TABLE parser_queue; 

您可以確定如果表是通過運行SHOW TABLE STATUS LIKE 'Data_Free',看看如果這樣會產生大量的碎片。

更新

你說你是存儲在TEXTgzcompress版數據。請嘗試將TEXT列更改爲BLOB,以此來處理二進制數據,例如壓縮文本。

+0

可悲的是,無濟於事嘗試了你的建議。更多細節添加到問題中。 – jisaacstone 2011-04-30 18:34:37

+0

爲你增加了一個新建議... :) – 2011-05-02 07:20:40

+1

更改爲BLOB可將查詢時間縮短75%。謝謝一堆。 – jisaacstone 2011-05-02 17:14:34

1

該名稱給出了您正在使用該表進行排隊(大量插入和刪除,也許?)。也許你有一段時間的桌子,而且它很分散。如果我的假設是正確的,嘗試OPTIMIZE TABLE parser_queue;

您可以在手冊中瞭解更多關於這一點: http://dev.mysql.com/doc/refman/5.1/en/optimize-table.html

1

權,這個問題似乎只有這個一直:在text領域地方過於龐大。

運行

SELECT id, status, last_updated FROM parser_queue 

花費的時間比

SELECT data FROM parser_queue WHERE id = 6 

時間不因爲我將要運行的回報只有一行的所有查詢,放緩會不會影響我這麼多。我已經在存儲的數據上使用了gzcompress,所以我認爲我無論如何不能做更多的事情。