2

我的网站在访问高峰期出现严重问题。在做了很多故障排除后,我发现问题出在数据库上。

我有这个在检索数据表的索引上运行的主查询。

在繁忙的一天,该网站第一次加载需要 30 到 45 秒,但之后每次加载速度都非常快,大约 5 分钟后再次变慢,最终网站因负载过多而崩溃。

我直接在数据库上测试了查询,它的执行完全相同。

这会更多地与查询或 MySQL 配置有关吗?

它在返回结果很小的情况下工作得非常好,但是在繁忙的一天,当列表非常大时,它真的会减慢速度并杀死网站。

编辑:

感谢您的所有建议。

我稍微修改了查询并对数据库进行了一些修改,因为有些名称不合理。

在您提出所有建议之后,我还修改了查询以删除通配符搜索以及对不再需要的表的一些冗余请求。

这是查询本身:

SELECT g.id, g.`name`, g.scores, g.sportFK, g.`desc`, g.`date`, s.id AS streamid
       FROM games AS g
       LEFT JOIN streams AS s ON s.gameFK = g.id
             WHERE
                  (g.date >= '" . $date . "' AND g.date <= '" . $newdate . "') 
                  AND g.sportFK IN (" .  $sportfk . ") 
                  ORDER BY g.date ASC"

经过测试,查询的第一次性能仍然在 33s 运行,随后的每次执行都在 0.04s 运行,这表明当高峰时间到来时,对站点的影响将是相同的。

我还准备了所需的信息EXPLAIN

这是用于“游戏”表的

游戏桌

GAMES TABLE:

SIZE: 6MB
ROWS: 14841
TYPE: INNODB

这是针对“STREAMS”表的

流表

STREAMS TABLE:

SIZE: 80MB
ROWS: 135296
TYPE: MyISAM

编辑:马丁感谢您对写作提出意见。该数据库确实以相当固定的时间间隔从另一个来源填充,因此将不断发生 READ 和 WRITE 操作。我将不得不对此做更多的研究。

4

3 回答 3

1

好吧,对于每个数据库开发人员来说,这个查询必须是性能恐惧 :-)

由于查询编译和执行计划计算,第一次可能会延长。您可以使用EXPLAIN.

由于该行为在 5 分钟内重复,我会说索引本身或缺少索引应该有问题。

您应该指定网站负载中是否只有读取或并发读取(使用您的查询)以及写入

一旦您还执行写操作,索引重新计算就会发挥作用。另一个可能的问题是锁定。假设每 5 分钟有人写入数据,查询非常复杂,因此它应该锁定表以进行写入事务,并且您的读取将等到提交/回滚。

请注意,这个查询非常复杂,而且永远不会很快——我的意思是非常快。

  • 使用索引对另一个表进行计数
  • 一个连接到另一个条件很大的表 - 连接本身是慢点
  • 两个 where 子句 => 两个索引
  • 使用另一个索引排序

您会看到有几个索引。写操作只是锁定表和索引并更新它们,你有 5 个。内部计数也不好。

如果您需要非常好的性能或定义经典方法,我会推荐更好的数据库或域设计:经常读取还是写入?而不是重新设计它。

于 2013-08-20T07:47:16.730 回答
1

可能发生的情况是,第一次运行查询的额外时间用于编译查询和制定执行计划。这会保持缓存一段时间,然后再次发生。

解决方案是将您的查询放入存储过程中。

于 2013-08-19T19:21:18.343 回答
0

如果多次执行查询,数据库在后台进行缓存以提高性能是正常的。如果你想提高性能,你可能需要一个解释计划,或者改进你的数据库结构或者改进你的查询结构。

为了改进数据库,检查解释计划并确保没有像全文扫描这样的昂贵操作。例如,您可能希望看到在 g.name 和连接列上添加索引的影响。尝试添加索引,看看成本改进。在缓慢写入时添加索引并增加数据库大小时要小心。

于 2013-08-19T19:24:25.787 回答