MySql - 极慢的简单查询(内存配置错误?)

时间:2016-04-10 09:16:05

标签: mysql database performance memory

我有一个非常大的数据库(~150GB),有许多不同大小的表。它运行在一台相对稳固的服务器上(16GB内存,8核Xeon),无论如何都不能满负荷运行(通常是RAM的一半,也是CPU的25%)。

但是随着数据库的增长,我越来越多的查询问题极其缓慢,即使在以下情况下:

  • 他们似乎已经过优化(至少已编入索引)
  • 他们不生成filesorts或tmp表
  • 他们不使用可能不适合内存的最大表格

它出现在各种查询中,但这是一个有时需要超过10mn(!)的查询示例:

SELECT A.*, B.*, C.*
    FROM A
    INNER JOIN B USING(id)
    LEFT OUTER JOIN C
        ON (A.id=C.id AND C.date="2016-01-10")
    WHERE A.field1 > 100
      AND  ( B.field2 REGEXP 'XX|YY'
          OR B.field3 REGEXP 'XX|YY' )

这是the associated EXPLAIN

表格大小&索引如下:

  • A:带有INDEX(id)的25MB
  • B:带有INDEX(id)的60MB
  • C:600MB带INDEX(id,日期)

好吧,它是B上的全表扫描,但只有200k行,并且表相对较小(至少它们可以适合内存)。指数看起来很好。那么世界上如何处理超过1000万呢?

另一个更简单的例子,花费超过10秒:

SELECT * FROM messages WHERE user_id=1 ORDER BY date ASC

解释说:

select_type     SIMPLE
table           messages
type            ref
possible_keys   user_id
key             user_id
key_len         8
ref             const
rows            5157
Extra           Using index condition; Using where

表消息大约为500MB,带有INDEX(user_id,date)。

请注意,所有表都使用myIsam(但此处的问题与表锁无关)。

我怀疑mySql配置不是最佳配置,并且阻止它使用空闲内存,从而使其使用磁盘访问,使一切变慢。事实上它甚至更简单的查询和&较小的表似乎暗示了配置问题。但这只是一个猜测,因为我没有看到还有什么可以解释这个。

另请注意,通常情况下,这些慢查询在重新执行时会更快(如果不是即时的)(因为我想象的缓存)。它们的缓慢还取决于当天的时刻(我注意到它在清晨更加糟糕),而资源从未用于满负荷。

有人知道会出现什么问题吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

我认为id是每个表中的PRIMARY KEY

C需要INDEX(date, id) - INDEX(date), INDEX(id)相同。

A需要INDEX(field1)(但可能无济于事)

除非您确实需要所有列,否则请勿使用*

如果您不需要LEFT JOIN,请使用JOIN。这样我为C提供的索引可能会更有用。

实际上,优化器决定B的全表扫描是唯一有用的入门方式。

请告诉我们REGEXPs到底是什么;可能有办法改善它们。

messages按此顺序需要INDEX(user_id, date)。请提供SHOW CREATE TABLE,以便我们确认您已经拥有该2列复合索引。

更改为InnoDB应该有所帮助。

对于MyISAM,key_buffer_size应设置为可用 RAM的大约20%。 (如果索引的总数(.MYI文件)小于该值,则可以更低。)在切换到InnoDB之前,innodb_buffer_pool_size应该为0.

如果重新执行“即时”运行,那么您正在使用查询缓存。我们忽略这一点。但是不要query_cache_size大于50M。

早上较慢?也许所有的缓存都很冷。这可能是因为每晚重启或备份。