简单的MySQL查询需要2到3秒?

时间:2009-08-19 07:10:31

标签: mysql performance

我有一个相当简单的流程,可以定期在MySQL数据库中提取RSS源和更新文章。

文章表现在填充到大约130k行。对于找到的每篇文章,处理器会检查文章是否已存在。这些查询几乎总是花费300毫秒,大约每10或20次尝试,它们需要超过2秒。

SELECT id FROM `articles` WHERE (guid = 'http://example.com/feed.rss')  LIMIT 1;
# Query_time: 2.754567  Lock_time: 0.000000  Rows_sent: 0  Rows_examined: 0

我在guid列上有一个索引,但每当遇到新文章时,它都会被添加到articles表中 - 使查询缓存无效(对吗?)。

慢查询日志中的一些其他字段报告检查了120多行。

当然,在我的开发机器上,这些查询大约需要0.2毫秒。

服务器是来自Engine Yard Solo(EC2)的虚拟主机,具有1.7GB内存和当前随附的CPU EC2。

非常感谢任何建议。

更新

事实证明问题出在椅子和键盘之间。

我有'id'的索引,但查询'guid'。

在'guid'上添加索引会使查询时间减少到每个0.2毫秒。

感谢大家提供的所有有用提示!

4 个答案:

答案 0 :(得分:4)

执行命令

EXPLAIN SELECT id FROM `articles` WHERE (guid = 'http://example.com/feed.rss')  LIMIT 1;

注意前面的EXPLAIN。那会告诉你MySQL在做什么。除非您的机器严重超载和/或颠簸,否则很难相信从索引探测一行可能需要2.7秒。考虑到行数为0,我猜测MySQL进行了全表扫描以找不到任何东西,这可能意味着你没有你认为你做的索引。

要回答您的其他问题,每当您对articles表进行任何更改时,涉及该表的所有查询缓存条目都将失效。

答案 1 :(得分:1)

日志显示没有读取或甚至检查过任何行,因此问题不在于您的查询,而在于您的服务器。 EC2的Achilles的脚跟是它的IO / s,也许MySQL必须从磁盘加载索引,但服务器的磁盘完全饱和。

如果索引足够小以适应内存(请确保my.cnf为key_buffer(MyISAM)或innodb_buffer_pool_size(InnoDB)分配足够的内存,你应该能够使用

预加载它
SELECT guid FROM articles

查看EXPLAIN,确保其显示“正在使用索引”。如果没有,那么这个应该:

SELECT guid FROM articles FORCE INDEX (guid) WHERE LENGTH(guid) > 0

或者,如果guid不是您的PRIMARY KEY或UNIQUE,您可以删除其索引并创建另一个索引列,用于以索引大小的一小部分快速检索记录。列guid_crc32将是INT UNSIGNED并且将保留guid的CRC32

ALTER TABLE articles ADD COLUMN guid_crc32 INT UNSIGNED, ADD INDEX guid_crc32 (guid_crc32);
UPDATE articles SET guid_crc32 = CRC32(guid);

您的SELECT查询将如下所示:

SELECT id FROM articles WHERE guid = 'http://example.com/feed.rss' AND guid_crc32 = CRC32('http://example.com/feed.rss') LIMIT 1;

优化程序应使用guid_crc32上的索引,该索引应该比搜索guid更快更小。

答案 2 :(得分:0)

如果此表得到更新,那么mysql可能无法正确更新索引计数。尝试“检查表文章”来更新索引计数,看看你的表是否正常。

还尝试查看对您的查询执行EXPLAIN是否在您的dev和prod计算机上提供相同的结果。如果结果不同,请尝试OPTIMIZE TABLE。

这些是myisam还是innodb表?

答案 3 :(得分:0)

假设GUID已编入索引且ID是您的主键,则表示“错误”。在那种情况下,它是一个仅索引查询。索引正在从内存中受到冲击,而且磁盘也很忙。

根据您的更新/插入/删除模式,您的数据库可能会因“优化”命令而哭泣。

SQL命令我想看看输出:

show table status like 'articles';
explain SELECT id FROM `articles` WHERE (guid = 'http://example.com/feed.rss')  LIMIT 1;
explain articles;

系统命令我想看看(假设Linux)的输出:

iostat 5 5

告诉我们你有多少记忆,因为1.7mb是错的,或者真正令人兴奋的事情正在发生。

编辑 my.cnf中SQL服务器可用的内存量是多少?