PHP-MySQL查询需要大量时间才能执行

我正在开发时间表应用程序,并编写PHP代码提取所有时间表直到日期.这是我为获取时间表而编写的查询-

选择a.accnt_name,u.username,DATE_FORMAT(t.in_time,’%H:%i’)inTime,DATE_FORMAT(t.out_time,’%H:%i’)outTime,DATE_FORMAT(t.work_time,’%H :%i’)工作时间,w.wrktyp_name,t.remarks,DATE_FORMAT(t.tmsht_date,’%d-%b-%Y’)tmshtDate,wl.loctn_name,s.serv_name,t.status_code,t.conv_kms convkms ,t.conv_amount从时间表t,帐户a,服务s,工作类型w,工作位置wl,用户WHERE a.accnt_code = t.accnt_code和w.wrktyp_code = t.wrktyp_code和wl.loctn_code = t.loctn_code和s.serv_code = t.serv_code和t.usr_code = u.按tmsht_date desc排序

where子句包含从各个表中获取各个代码的实际值的子句.

问题在于此查询需要花费大量时间来执行,并且应用程序在几分钟后崩溃.

我在PHPmyadmin中运行了此查询,在这里它没有任何问题.

需要帮助来了解执行速度缓慢背后的原因.

解决方法:

使用EXPLAIN查看查询的执行计划.确保MysqL有合适的可用索引,并且正在使用这些索引.

查询文本似乎缺少此处的列名…

  t.usr_code = u.    ORDER
                 ^^^

我们可以“猜测”应该是u.usr_code的代码,但这只是一个猜测.

应该返回多少行?结果集有多大?

您的客户端是否要尝试将所有行“存储”在内存中,并因为内存不足而崩溃?

如果是这样,我建议您避免这样做,并在需要时获取行.

或者,考虑在WHERE子句中添加一些其他谓词,以仅返回所需的行,而不返回表中的所有行.

现在是2015年.该放弃老式的逗号语法进行联接操作了,改为使用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语句.

我们不希望执行sql语句导致PHP“崩溃”.

如果要存储整个结果集(例如,使用MysqLi store_result),则需要具有足够的内存.但是选择列表中的13个表达式看起来都比较短(格式化的日期,名称代码),并且我们不希望“备注”超过2 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 

我怀疑查询不是您观察到的行为的根本原因.我怀疑问题出在代码的其他地方.

How to debug small programs http://ericlippert.com/2014/03/05/how-to-debug-small-programs/

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...