使用 cron 时的 MySQL 性能差异

Posted

技术标签:

【中文标题】使用 cron 时的 MySQL 性能差异【英文标题】:MySQL performance differences when using cron 【发布时间】:2012-12-29 06:53:28 【问题描述】:

我有许多 php 维护脚本在使用 cPanel 的共享主机环境上运行。大多数脚本需要每 3-4 小时运行一次,为了简化它们的执行,我编写了一个调度程序脚本来检查这些脚本中的哪些(如果有)需要运行并在必要时执行它们。我将调度程序脚本设置为在 cron 中每 5 分钟运行一次。如果脚本发现当前没有任何维护任务到期,它什么也不做。调用调度程序的开销导致执行大约 5 个短 SQL 查询(因此这些查询每 5 分钟执行一次)。

一切正常,直到我的主机抱怨 mysql 使用率高,声称我远远超出了允许的限制。禁用调度程序 cron 作业后,我的资源使用量下降到 0。

在禁用 cron 作业之前: MySQL procs 数(平均) - 0.97 禁用 cron 作业后: MySQL procs 数(平均) - 0.00

奇怪的是,在删除 cron 作业后,我仍然每隔几个小时通过浏览器手动激活调度程序脚本。由于脚本仍在运行,我对 MySQL 进程的平均数量大幅下降感到非常惊讶。在禁用 cron 作业之前,我开始记录调度程序和维护脚本执行了多少 SQL 查询。

在禁用 cron 作业之前:每天 9899 次查询(平均) 禁用 cron 作业后: 每天 9552 次查询(平均)

因此,当我手动调用调度程序时,它仍然执行几乎与 cron 一样多的 SQL 查询,但不知何故,我的 MySQL 使用率仍然下降到基本上没有。

使用 php 命令通过 cron 作业执行 PHP 脚本与通过浏览器调用它之间是否存在与性能相关的差异?我没有在我的脚本中明确关闭数据库连接,因为我的理解是这会在执行结束时自动发生。当脚本通过 cron 运行时,此连接是否可能保持打开状态?使用 cron 时性能的显着差异还有哪些其他解释?

【问题讨论】:

打赌你不是每 5 分钟从浏览器运行一次作业。 不,我不是——但就像我上面所说的,每天执行的查询总数保持不变。每 5 分钟创建一次数据库连接可能会产生很大的开销? 也许您没有运行的 347 个查询是造成大部分负载的原因? 如果通过 cron 运行脚本和通过浏览器请求运行脚本之间没有其他区别,那么您可能是对的。只是在大多数情况下,调度程序脚本执行的唯一附加查询是对少于 100 行的表的简单选择语句,因此它们不是长时间运行的查询。我也想知道 cPanel 提供的统计数据是否不是很准确。 你试过解释查询吗?以及什么时期的平均值? 5 分钟? 7 小时? 【参考方案1】:

通常,两个 php.ini 文件与 PHP 一起安装:

一个用于 Apache 一个用于 CLI(命令行界面)

通常,cron 作业将执行 php -f yourfile.php,它使用 CLI php.ini 文件。同样,当您通过网络和通过 apache 调用脚本时,它将使用 apache php.ini 文件。此外,apache 允许在您的虚拟主机配置或.htaccess 文件中使用php_valuephp_flag

您很可能在 apache 和 CLI 之间存在配置差异。

我首先想到的是持久的数据库连接。持久连接将使用 pool 到您的数据库服务器的连接,这些连接将在请求之间 persist 保持打开状态,以避免 TCP 握手。这是一项性能优化,但可能会超出 MySQL 服务器的连接限制。

在我的系统 (Ubuntu) 上,两个 php.ini 文件的路径如下:

/etc/php5/apache2/php.ini /etc/php5/cli/php.ini

您可以通过-c 标志在命令行上运行php 时指定要使用的php.ini 文件。

【讨论】:

我无权访问共享主机环境中的默认 php.ini 文件,但我能够创建自己的并配置 cron 作业以使用它,而不是像您一样使用 -c 标志说。每 5 分钟运行一次作业似乎仍然会使我的 MySQL 资源使用超载,但将 mysql.allow_persistent = "0" 添加到我的自定义 php.ini 文件肯定会有所作为。谢谢!

以上是关于使用 cron 时的 MySQL 性能差异的主要内容,如果未能解决你的问题,请参考以下文章

MySQL使用默认值与在查询中设置值是不是有任何性能差异?

使用比较运算符时的 MYSQL 性能

Native SQL(使用 MySQL)与使用 Hibernate ORM 的性能差异?

使用 MySQL VIEW 时的性能注意事项

Spark 3.0 - 使用 .save() 或 .saveAsTable() 保存时的读取性能

BEFORE 触发器和 ON UPDATE CURRENT_TIMESTAMP 之间的性能差异 - MySQL