2

此查询需要很长时间才能产生结果。并在 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

4 回答 4

3

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

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

于 2012-08-18T13:08:03.447 回答
0

你的问题是NOT IN。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 存储为 datetime 数据类型,而不是字符串。这样,与 CURRENT_DATE 的比较不包括隐式转换。
  3. 如果“tow_mac_address”包含编码信息,请考虑将其拆分为单独的字段。
于 2012-08-18T16:22:53.267 回答
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列上使用索引。

于 2012-08-18T13:18:00.093 回答
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

   

于 2012-08-18T13:25:24.017 回答