2015-03-27 2 views
0

Я написал следующий запрос, чтобы найти повторяющиеся метки времени в пределах диапазона дат с намерением удалить эти дубликаты с большим идентификатором. Однако этот выбор никогда не завершается.Запрос на поиск повторяющихся временных меток MySQL

SELECT 
    * 
FROM 
    data 
WHERE 
id NOT IN (SELECT 
     MIN(id) 
    FROM 
     data 
    WHERE 
     datapoint_name LIKE 'Temp%' 
      AND timestamp BETWEEN '2012-07-31' AND '2012-08-03' 
    group by timestamp , datapoint_name) 
AND datapoint_name LIKE 'Temp%' 
AND timestamp BETWEEN '2012-07-31' AND '2012-08-03'; 

Мне кажется странным, что отдельные компоненты работают очень быстро и не так много строк. В частности:

  • SELECT MIN (ID) ... GROUP BY подзапрос возвращает 476 строк в .7 сек.
  • внешний SELECT * без id NOT IN() возвращает 490 строк в 0,001 сек.

Другими словами, существует 14 дубликатов, но операция NOT IN(), по-видимому, занимает непомерное количество времени. На самом деле, у меня никогда не было терпения, чтобы посмотреть, не закончится ли она. Что я могу сделать, чтобы ускорить это? Я сделал что-то принципиально неправильно?

+0

, сколько строк в этой таблице? Учтите, что ваш внутренний запрос возвращает в основном один единственный идентификатор, который затем должен сравниваться с каждым ДРУГОЙ идентификатором в таблице. например если есть миллион записей, вы будете делать 1 000 000 * 999,999 сравнений с этим 'not in'. –

ответ

1

Причина, вероятно, в том, что подзапрос повторно выполняется для каждой сравниваемой строки. Попробуйте переместить подзапрос к from и используя left join:

SELECT d.* 
FROM data d LEFT JOIN 
    (SELECT timestamp, datpoint_name, MIN(id) as minid 
     FROM data 
     WHERE datapoint_name LIKE 'Temp%' AND 
      timestamp BETWEEN '2012-07-31' AND '2012-08-03' 
    GROUP BY timestamp , datapoint_name 
    ) dd 
    ON d.datapoint_name = dd.datapoint_name and 
     d.timestamp = dd.timestamp and 
     d.id = dd.minid 
WHERE d.datapoint_name LIKE 'Temp%' AND 
     d.timestamp BETWEEN '2012-07-31' AND '2012-08-03' AND 
     dd.minid IS NULL; 
+0

Мне понадобится минутка, чтобы распаковать ваш ответ (я довольно новичок в MySQL), но это сработало как шарм. – Kris

Смежные вопросы