mysql查询耗时太长

时间:2012-08-18 13:03:29

标签: php mysql internal-server-error

此查询生成结果所需的时间太长。在php页面中,它会创建500内部服务器错误。

SELECT DISTINCT tower_mac_address AS MAC_Address, tower_survey_no AS Survey_No 
FROM tower 
WHERE 
SUBSTR(REPLACE(tower_mac_address,':',''),7,6) 
NOT IN 
    (SELECT DISTINCT deviceid FROM device_data 
    WHERE SUBSTRING(date_time,1,10)=CURRENT_DATE)

请帮助

4 个答案:

答案 0 :(得分:3)

您的查询非常糟糕。由于您正在使用SUBSTR(REPLACE .....它不能在tower_mac_address列上使用索引。对于该内部查询的类似情况,您再次使用SUBSTR ...而不是这样做,您可以准备具有该SUBSTR的新列(已经替换......并在该列上添加索引。

顺便说一句,当您计算应该用于内部WHERE的值时,请使用DATE()函数来代替使用SUBSTRING获取日期时间的日期时间。

答案 1 :(得分:0)

你绝对可以在子查询中删除substring

SELECT DISTINCT deviceid FROM device_data 
WHERE SUBSTRING(date_time,1,10)=CURRENT_DATE;

--is the same as 
SELECT DISTINCT deviceid FROM device_data
WHERE `date_time` >=CURRENT_DATE AND `date_time`<CURRENT_DATE+INTERVAL 1 DAY;

但第二个查询可以使用date_time列上的索引。

答案 2 :(得分:0)

试试这个

SELECT DISTINCT tower_mac_address AS  MAC_Address, tower_survey_no AS Survey_No 
FROM tower LEFT JOIN
(SELECT DISTINCT deviceid FROM device_data WHERE SUBSTR(date_time,1,10)=CURRENT_DATE) d ON SUBSTR(REPLACE(tower_mac_address,':',''),7,6) = d.deviceid
WHERE d.deviceid IS NOT NULL

答案 3 :(得分:0)

你的问题是没有。 MySQL在优化这项工作方面做得很差。至少文档有点解释了这一点。

SELECT DISTINCT tower_mac_address AS MAC_Address, tower_survey_no AS Survey_No 
FROM tower t
WHERE  not exists
       (select 1
        from device_data dd
        where dd.deviceid = SUBSTR(REPLACE(t.tower_mac_address,':',''),7,6) and
              SUBSTRING(date_time,1,10)=CURRENT_DATE
       )

以下是其他建议:

  1. 在device_data.deviceid上构建索引以加速子查询。
  2. 将date_time存储为日期时间数据类型,而不是字符串。这样,与CURRENT_DATE的比较不包括隐式转换。
  3. 如果“tow_mac_address”包含编码信息,请考虑将其拆分为单独的字段。