php - 优化 PHP 页面 : MySQL bottleneck

标签 php optimization mysql

我有一个页面需要 37 秒才能加载。当它加载时,它会通过屋顶挂住 MySQL 的 CPU 使用率。我没有为这个页面编写代码,它相当复杂,所以瓶颈的原因对我来说并不明显。

我分析了它(使用 kcachegrind)并发现页面上的大部分时间花在了 MySQL 查询上(90% 的时间花在了 25 个不同的 mysql_query 调用上)。

查询采用以下形式,其中 tag_id 在 25 次不同的调用中的每一次发生变化:

SELECT * FROM tbl_news WHERE news_id
 IN (select news_id from
 tbl_tag_relations WHERE tag_id = 20)

每个查询大约需要 0.8 秒才能完成,为了更好地衡量,还会有一些更长的延迟……因此需要 37 秒才能完全加载页面。

我的问题是,导致问题的是使用嵌套选择格式化查询的方式吗?或者它可能是一百万种其他事物中的任何一种?对于如何解决这种缓慢的任何建议,我们表示赞赏。

在查询上运行 EXPLAIN 给我这个(但我不清楚这些结果的影响......主键上的 NULL 看起来很糟糕,是吗?返回的结果数量对我来说似乎很高以及最后只返回少量结果):

1    PRIMARY     tbl_news   ALL NULL    NULL    NULL    NULL    1318    Using where
2   DEPENDENT SUBQUERY  tbl_tag_relations   ref FK_tbl_tag_tags_1   FK_tbl_tag_tags_1   4   const   179 Using where

最佳答案

我在 Database Development Mistakes Made by AppDevelopers 中解决了这一点.基本上,赞成加入聚合。 IN 本身不是聚合,但适用相同的原则。一个好的优化将使这两个查询在性能上相当:

SELECT * FROM tbl_news WHERE news_id
 IN (select news_id from
 tbl_tag_relations WHERE tag_id = 20)

SELECT tn.*
FROM tbl_news tn
JOIN tbl_tag_relations ttr ON ttr.news_id = tn.news_id
WHERE ttr.tag_id = 20

我相信 Oracle 和 SQL Server 都可以,但 MySQL 不会。第二个版本基本上是瞬时的。对于数十万行,我在我的机器上进行了测试,并通过添加适当的索引获得了亚秒级性能的第一个版本。带有索引的连接版本基本上是瞬时的,但即使没有索引也可以执行。

顺便说一句,我使用的上述语法是您在进行连接时应该更喜欢的语法。它比将它们放在 WHERE 子句中(正如其他人所建议的那样)更清楚,并且上面可以用 ANSI SQL 方式使用 WHERE 条件不能做的左外连接来做某些事情。

所以我会在以下内容上添加索引:

  • tbl_news (news_id)
  • tbl_tag_relations (news_id)
  • tbl_tag_relations (tag_id)

查询几乎会立即执行。

最后,不要使用 * 来选择您想要的所有列。明确命名它们。稍后添加列时,您会遇到更少的麻烦。

关于php - 优化 PHP 页面 : MySQL bottleneck,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/789957/

相关文章:

javascript - 从数据库中填充 fullcalendar javascript 中的事件

php - ORDER BY 日期同时也在 MySQL 查询中使用 LIMIT - PHP

MYSQL less Than函数不能正常工作

javascript - 如何在更改 header js 类和 CSS 时更改 php header 中的 Logo

php - 在连接查询 SQL 上全选

javascript - 使用单选按钮将值从 html 表单传递到 javascript 函数

javascript - 压缩效率

javascript - 在 V8 中扩展 JavaScript 数组并维护 PACKED 类型

python - DataFrame 多目标排序定义 Pareto 边界

php - 检查数据库中的记录是否存在 php mysqli