2011-04-30 148 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,所以我认为我无论如何不能做更多的事情。