Php Mysql查询执行起来需要很多时间
我正在开发一个时间表应用程序,并编写一个PHP代码来获取截止日期的所有时间表。这是我为获取时间表而编写的查询-Php Mysql查询执行起来需要很多时间,php,mysql,Php,Mysql,我正在开发一个时间表应用程序,并编写一个PHP代码来获取截止日期的所有时间表。这是我为获取时间表而编写的查询- 选择a.accnt\u名称、u.username、DATE\u格式(t.in\u time、%H:%i')inTime、DATE\u格式(t.out\u time、%H:%i')outTime、DATE\u格式(t.work\u time、%H:%i')workTime、w.wrktyp\u name、t.备注、DATE\u格式(t.tmsht\u DATE、%d-%b-%Y')tms
选择a.accnt\u名称、u.username、DATE\u格式(t.in\u time、%H:%i')inTime、DATE\u格式(t.out\u time、%H:%i')outTime、DATE\u格式(t.work\u time、%H:%i')workTime、w.wrktyp\u name、t.备注、DATE\u格式(t.tmsht\u DATE、%d-%b-%Y')tmshtDate、wl.loctn\u名称、s.serv\u名称、t.status\u代码、t.convkms convkms convkms convkms、convamount FROM,账户a、服务s、工作类型w、工作地点wl、其中a.accnt_代码=t.accnt_代码和w.wrktyp_代码=t.wrktyp_代码和wl.loctn_代码=t.loctn_代码和s.serv_代码=t.serv_代码和t.usr_代码=u的用户。按tmsht_日期说明订购
where子句包含从各个表中获取各个代码的实际值的子句
问题是执行此查询需要花费大量时间,并且应用程序在几分钟后崩溃
我在phpmyadmin中运行了这个查询,在那里它可以正常工作
需要帮助了解执行缓慢背后的原因。phpadmin会自动为查询添加限制,这就是为什么您可以快速获得结果
使用EXPLAIN查看查询的执行计划。确保MySQL有合适的可用索引,并且正在使用这些索引 查询文本似乎缺少此处列的名称
t.usr_code = u. ORDER
^^^
我们可以“猜测”那应该是u.usr\u code
,但那只是猜测
应该返回多少行?结果集有多大
您的客户端是否试图“存储”内存中的所有行,并因为内存不足而崩溃
如果是这样,我建议您避免这样做,并根据需要获取行
或者,考虑在WHERE子句中添加一些额外的谓词来返回您需要的行,而不是返回表中的所有行。
现在是2015年。是时候抛弃join操作的老式逗号语法了,改用join
关键字,并将join谓词从WHERE
子句移动到ON
子句。并格式化它。数据库并不在意,但它会让需要破译SQL语句的可怜人更容易理解
SELECT a.accnt_name
, u.username
, DATE_FORMAT(t.in_time ,'%H:%i') AS inTime
, DATE_FORMAT(t.out_time ,'%H:%i') AS outTime
, DATE_FORMAT(t.work_time,'%H:%i') AS workTime
, w.wrktyp_name
, t.remarks
, DATE_FORMAT(t.tmsht_date, '%d-%b-%Y') AS tmshtDate
, wl.loctn_name
, s.serv_name
, t.status_code
, t.conv_kms AS convkms
, t.conv_amount AS convamount
FROM timesheets t
JOIN accounts a
ON a.accnt_code = t.accnt_code
JOIN services s
ON s.serv_code = t.serv_code
JOIN worktypes w
ON w.wrktyp_code = t.wrktyp_code
JOIN work_location wl
ON wl.loctn_code = t.loctn_code
JOIN users
ON u.usr_code = t.usr_code
ORDER BY t.tmsht_date DESC
格式化日期列上的排序非常奇怪。更可能的情况是,您希望结果以“日期”顺序返回,而不是以字符串顺序返回,以月份和日期为前一年。(您真的想先按日期值排序,在年份之前吗?)
跟进
如果使用来自不同客户机(同一数据库、同一用户)的整个结果集(约720行)快速完成相同的精确查询,那么问题可能不是此SQL语句
SELECT a.accnt_name
, u.username
, DATE_FORMAT(t.in_time ,'%H:%i') AS inTime
, DATE_FORMAT(t.out_time ,'%H:%i') AS outTime
, DATE_FORMAT(t.work_time,'%H:%i') AS workTime
, w.wrktyp_name
, t.remarks
, DATE_FORMAT(t.tmsht_date, '%d-%b-%Y') AS tmshtDate
, wl.loctn_name
, s.serv_name
, t.status_code
, t.conv_kms AS convkms
, t.conv_amount AS convamount
FROM timesheets t
JOIN accounts a
ON a.accnt_code = t.accnt_code
JOIN services s
ON s.serv_code = t.serv_code
JOIN worktypes w
ON w.wrktyp_code = t.wrktyp_code
JOIN work_location wl
ON wl.loctn_code = t.loctn_code
JOIN users
ON u.usr_code = t.usr_code
ORDER BY t.tmsht_date DESC
我们不希望SQL语句的执行导致PHP“崩溃”
如果要存储整个结果集(例如,使用mysqli store_result),则需要有足够的内存。但是select列表中的13个表达式看起来都相对较短(格式化日期、名称和代码),我们不希望“备注”超过几KB
如其他人所建议的那样,为了调试此操作,请尝试在查询中添加一个LIMIT子句,例如LIMIT 1
,并观察其行为
或者,使用虚拟查询进行测试;使用保证返回特定值和特定行数的查询
SELECT 'morpheus' AS accnt_name
, 'trinity' AS username
, '01:23' AS inTime
, '04:56' AS outTime
, '00:45' AS workTime
, 'neo' AS wrktyp_name
, 'yada yada yada' AS remarks
, '27-May-2015' AS tmshtDate
, 'zion' AS loctn_name
, 'nebuchadnezzar' AS serv_name
, '' AS status_code
, '123' AS convkms
, '5678' AS convamount
我怀疑该查询不是您正在观察的行为的根本原因。我怀疑问题出在代码的其他地方
首先:修改您的查询,使其看起来像斯宾塞给出的查询 当你的应用程序“崩溃”时,你会收到错误消息吗?还是只是停止了 你可以试试:
ini_set('max_execution_time', 0);
在php代码中。这将最大执行时间设置为无限。因此,如果没有错误,脚本应该执行到最后。因此,您可以查看查询是否得到所需的结果
同样,作为一个测试,使用
LIMIT 10
这将大大加快您的查询速度,因为它只需要前十个结果。
您可以稍后将此值更改为更适合您需要的值。除非您绝对需要完整的结果集,否则我建议您在查询中始终使用LIMIT。可以对选择的字段使用索引以加快执行速度感谢您的详细回答。我完全同意应该使用JOIN而不是传统的where子句。你关于根据格式化日期排序的观点也是很好的。我没有注意到这一点。然而,即使我将代码更改为您给出的代码,问题仍然存在。这是我第一次面对这样的问题。而且关于结果中记录的数量不是很高。大约有720条记录。我也相信这个查询不是你问题的原因。您是运行本地sql server还是在共享主机上运行sql server?几年前,我是一家sharede托管服务公司,由于产能过剩,它的sql server速度非常慢。一个简单的sql语句花费的时间太长。也许你也是这样。我正在运行一个本地mysql实例。我在一个共享主机上也有它,但是我的本地实例本身有问题。
max\u execution\u time
设置有点有用。页面运行了很长时间,没有出现错误,但它打印了我给出的几个回音。