MySQL查询主键上的慢查询表

时间:2011-06-02 02:39:18

标签: mysql innodb

所以我有一个基本上像NoSQL设置一样使用的表。结构是:

id bigint主键 数据媒体 修改后的时间戳

它有大约350k行。在其上运行的查询的结构如下:

从表格中选择数据,其中id = XXX;

表引擎是InnoDB。我注意到有时针对此表运行的查询相当慢。有时它们需要3秒才能运行。该表在磁盘上是3 GB,我给了innodb_buffer_pool_size 4G。

这里有什么我想念的吗?我可以调整哪些设置来提高性能吗?

编辑:按要求解释输出:

+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table    | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | cache    | const | PRIMARY       | PRIMARY | 8       | const |    1 |       |
+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+

创建表格:

CREATE TABLE `cache` (
  `id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `data` mediumblob,
  `modified` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

4 个答案:

答案 0 :(得分:6)

我最初在这里看到两个问题。首先,您有一个blob数据类型的查询。在数据检索方面,这将导致速度问题。其次,您正在使用InnoDB,它针对写入进行了优化。这意味着虽然它可能是整体上的最佳选择,但在极端阅读情况下,其性能可能不如MyISAM。这些问题都不一定是交易杀手,但它们都会增加性能。然而,除此之外,我不确定如果没有先进行分析,我可以为您提供更好的答案,以便更好地进行优化。这就是我建议你先做的事情。描述您的查询以确定执行计划是什么,然后确定执行计划如此缓慢的原因。

这是一个很好的“十大”MySQL优化列表。至少有一对夫妇直接适用于您的情况:

http://20bits.com/articles/10-tips-for-optimizing-mysql-queries-that-dont-suck/

这是另一个很好的优化文章,也可以进入服务器设置(特别是InnoDB):

http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/

根据您提供的CREATE TABLE语句,我确实想到了您应该解决的另一件事(同样,不是查询杀手,但它是另一个性能损失)。除非存在为您的ID字段使用bigint的业务案例,否则请选择int。一个int将允许21亿行,所以你不应该用完数字。进行此切换将节省磁盘空间,并将提高查询性能。这是一篇关于它的文章:

http://ronaldbradford.com/blog/bigint-v-int-is-there-a-big-deal-2008-07-18/

答案 1 :(得分:0)

您可以发布CREATE TABLE声明以及EXPLAIN select data from table where id=XXX的输出吗? io如何在系统上等待?

我最好的猜测是你受IO限制,因为行的大小不一样,所以必须搜索数据。你有足够的内存,它应该能够保持数据缓存。此链接描述了MySQL中可能有用的一些低级概要分析。

http://dev.mysql.com/tech-resources/articles/using-new-query-profiler.html

答案 2 :(得分:0)

尝试尽可能使用最小ID。如果它是一个你知道永远不会超过几百万的数字键,你可以使用MEDIUMINT UNSIGNED并为INT上的每条记录保存一个字节,这可能会加快搜索速度。不过,只有350,000行,3 GB是非常多的。

通过使用partitioning feature将您的桌子拆分为逻辑单元,听起来您可能会有所收获。你可能想特别对谷歌“mysql垂直分区”;如果您不经常访问大型列,将它们移出到单独的表中并且仅在需要时查询它会更有效。

答案 3 :(得分:0)

我会寻找的东西:

  • 什么时候出现慢查询?

    • 是在DB重新开始之后吗?那么这可能只是一个临时问题 - 查询在冷缓存中命中
    • 是在DB转储/加载期间吗? - 然后更改备份策略 - 例如使用复制,或添加更多磁盘IO(在RAID中添加更多磁盘,将磁盘更改为SSD,在多个磁盘上重新分区系统等)
    • 是高峰读/写时间吗?复制也可能在这里有所帮助 - 写入主服务器和负载平衡主服务器和从服务器之间的读取
  • 另外 - 中脑真的有必要吗?