为了账号安全,请及时绑定邮箱和手机立即绑定

在单个 PHP 脚本执行中显示所有 SQL 查询

在单个 PHP 脚本执行中显示所有 SQL 查询

PHP
蝴蝶不菲 2022-11-04 16:35:44
PHP 有一个长期存在的大型项目,在其开发过程中,在不同时期涉及了许多不同的开发人员。潜在地,在错误修复期间可能存在重复数据库查询的地方。一些解决本地问题的开发人员可以编写并执行查询,返回先前获得的数据。现在在项目上存在数据库性能问题,因此有一个问题:是否有任何工具(除了常规日志)可以让您查看作为单个 PHP 脚本执行的一部分进行了哪些数据库查询?这个问题与项目中有很多API端点有关,仅通过阅读代码(有时非常华丽)来检查它们需要很长时间。
查看完整描述

1 回答

?
紫衣仙女

TA贡献1839条经验 获得超15个赞

大多数 PHP 框架使用单个连接接口 - 某种包装器 - 这使得通过该接口记录所有查询成为可能。


如果不存在另一种方法是在 MySQL 级别启用日志记录。但对于某些人来说,可能是合法的,你也不想这样做。如果您想防止停机,您实际上可以在不重新启动 MySQL 服务器的情况下启用查询日志记录。


如果上述解决方案均不可行,则您必须弄脏自己的手:-)


一种方法是在 PHP 代码中添加您自己的日志记录。如果写入文件末尾,则向文件写入新行不是性能问题。


我不确定你如何查询数据库,但如果你..


A) ..使用程序 mysqli 函数


如果您使用 mysqli_query() 之类的过程 mysqli 函数来调用数据库,您可以创建自己的全局自定义函数,该函数写入日志文件,然后调用真正的函数。


一个例子:


添加新的全局函数:


function _mysqli_query($link, $query, $resultmode = MYSQLI_STORE_RESULT )

{

    // write new line to end of log-file

    file_put_contents('queries.log', $query . "\n", FILE_APPEND);


    // call real mysqli_query

    return mysqli_query($link, $query, $resultmode);

}

在项目范围内搜索并替换mysqli_query(和_mysqli_query(。


然后是这样的一行:


$result = mysqli_query($conn, 'select * from users');

搜索和替换后看起来像这样:


$result = _mysqli_query($conn, 'select * from users');

B) ..使用 mysqli 类(面向对象风格)


如果您通过实例化 mysqli 类来使用面向对象的风格,然后调用查询方法,例如 $mysqli->query("select * from users") 一种方法可能是创建您自己的数据库类,它扩展了 mysqli 类,并在内部您在上面的示例中添加日志记录的具体方法(例如查询功能)。


在 O'Reilly 的高度推荐书“高性能 MySQL”中,他们通过代码示例了解如何执行此操作并添加额外的调试信息(时间等)。某些页面可在 google 图书中访问。


一般来说


我会考虑利用这个机会来更好地重构一些代码库。


如果您编写了自动化测试,这是确保重构不会破坏任何东西的好方法。


如果您不练习自动化测试,则必须手动测试整个应用程序。


您说您担心您的性能问题来自重复的数据库查询,这很可能是这种情况。在大多数情况下,我发现它缺少索引或者需要重写单个查询。


如果您发现它可能是导致性能问题的其他原因,那么 MySQL 中的性能模式可以帮助您调试这些东西。


查看完整回答
反对 回复 2022-11-04
  • 1 回答
  • 0 关注
  • 82 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信