【问题标题】:Mysql slow log: simple select query takes 26 secondsmysql慢日志:简单select查询耗时26秒
【发布时间】:2015-01-24 14:51:10
【问题描述】:

我有一个使用 InnoDB 的简单表:

tag_id int(20), primary
tag varchar(50)

表中只有 106 个标签,有时这个简单的选择查询需要 10s、16s、30s 或更多:

# Query_time: 26  Lock_time: 0  Rows_sent: 106  Rows_examined: 106
use database;
SELECT `tag`
FROM (`tags`);

我的问题:有没有办法优化这个查询(所以它不会需要 26 秒才能完成)或者这是 MySQL 服务器过载的明显迹象?如果我从共享主机升级到 VPS,我会解决这个问题吗?

【问题讨论】:

  • 您是否尝试过执行 EXPLAIN(EXPLAIN SELECT tag FROM tags)?这应该提供有关如何执行查询的更多信息。另外,手动运行查询实际上需要那么长时间吗?
  • @superultranova 如果我手动运行查询,我会得到正常的结果,大约快 30.000 倍(cca. 0,0007s 或类似的东西)。似乎这种长查询时间只是偶尔在仅持续几分钟的时间间隔内发生。如果我运行 EXPLAIN,我会得到这个,但我不知道如何处理它:'id' => string '1' (length=1) 'select_type' => string 'SIMPLE' (length=6) 'table' => string 'tags' (length=7) 'type' => string 'ALL' (length=3) 'possible_keys' => null 'key' => null 'key_len' => null 'ref' => null 'rows' => string '106' (length=3) 'Extra' => string '' (length=0)

标签: mysql database mysql-slow-query-log


【解决方案1】:

如果你强制它使用主键而不是进行全表扫描,它可能会更快。如果您使用的是 innodb,请尝试执行 SELECT tag FROM tags USE INDEX(PRIMARY)。或者,您也可以将WHERE tag_id > 0 添加到您的查询中。据我了解,如果查询中没有使用索引,innodb 会进行范围扫描,与索引扫描相比,它的成本更高。如果你强制它使用索引,它会扫描索引来查找表的所有行,这可能会更快。不过这里可能还有更多内容,我不像以前那样精通 mysql/innodb 内部结构。

如果不是,那么我猜瓶颈在其他地方(可能是 HDD I/O)。在这种情况下,升级到不同的服务器并不是唯一的解决方案(尽管它可能会解决问题)。如果该表不是不断变化的(即每隔几秒更改一次),则可能值得使用某种内存缓存机制,例如 memchached(还有其他机制)。如果您遇到 I/O 问题,使用内存缓存来存储该表和/或其他表中的数据可能值得研究。您可能会发现一个具有更快磁盘 I/O 的主机,但无论您如何对其进行切片,对磁盘的读取和写入都是昂贵的。想出某种缓存过程可能是值得的。

【讨论】:

  • 在我的手动测试中,查询速度从 0.0003 到 0.0005。如果我使用 INDEX(PRIMARY) 没有什么真正改变。这只是一个 106 行的小表,明年可能会增长到 110 行。我将尝试实现某种缓存或只是升级到更好的托管。
  • 这很典型,根据您在监视器中看到的判断命令速度可能会有问题。在负载下执行查询所需的时间可能完全不同,如果文件 I/O 饱和,索引扫描和范围扫描之间的速度可能会有很大差异。如果表没有太大变化,内存缓存会很好地为您服务。
猜你喜欢
  • 1970-01-01
  • 2021-10-28
  • 2013-04-08
  • 2012-06-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-13
  • 1970-01-01
相关资源
最近更新 更多