2015-11-30 4 views
1

Я новичок в SQL и у меня проблема с моими подзапросами ниже. Причина, по которой я настроил подзапрос, - это упорядочить и сгруппировать столбец иначе, чем то, как данные сортируются в главной таблице. Есть ли другие способы оптимизации этого запроса? Он отключился и работает более 30 минут. Я хотел бы избегать повторного сканирования таблицы piwik_log_visit как можно больше. Есть ли способ упорядочивать или группировать только по определенным столбцам? Я ценю любую помощь. Спасибо!sql-запрос с оптимизацией подзапросов

Set @theDate = cast('2015-11-26 08:00:00' as datetime); 

SELECT t2.idorder AS 'Order ID', 
     (
      SELECT COALESCE(NULLIF(t3.referer_name,''), 'Direct') 
      FROM piwik_log_visit t3 
      WHERE conv(hex(t3.idvisitor), 16, 10) = conv(hex(t2.idvisitor), 16, 10) 
      AND  t3.visit_first_action_time >= (@theDate - INTERVAL 32 DAY) 
      ORDER BY t3.visit_last_action_time DESC 
      limit 1 
     ) AS 'Referrer (Last)', 
     (
      SELECT COALESCE(NULLIF(t4.referer_name,''), 'Direct') 
      FROM piwik_log_visit t4 
      WHERE inet_ntoa(conv(hex(t4.location_ip), 16, 10)) = inet_ntoa(conv(hex(t1.location_ip), 16, 10)) 
      AND  t4.visit_first_action_time >= (@theDate - INTERVAL 32 DAY) 
      GROUP BY inet_ntoa(conv(hex(t4.location_ip), 16, 10)) 
      ORDER BY t4.visit_first_action_time 
      limit 1 
     ) AS 'Referrer (IP:First)', 
     t1.referer_url AS 'Referrer URL' 
FROM piwik_log_visit t1, 
     piwik_log_conversion t2 
WHERE conv(hex(t1.idvisitor), 16, 10) = conv(hex(t2.idvisitor), 16, 10) 
AND  t2.idorder IS NOT NULL 
AND  t2.server_time BETWEEN '2015-11-25 07:59:59' AND '2015-11-26 08:00:00' 
AND  t1.visit_first_action_time >= (@theDate - INTERVAL 32 DAY) 
GROUP BY t2.idorder 

Объяснить план:

http://screencast.com/t/3loUAUkTe

+0

Можете ли вы представить свой план объяснить? http://www.sitepoint.com/explain-sql-explain-queries/ –

+0

@JuanCarlosOropeza - это то, что вам нужно -http: //screencast.com/t/3loUAUkTe – nsilence

+0

Переформулированный вопрос: что вы хотите, чтобы ваш результат быть? –

ответ

1

Основной причиной плохой работы из-за условий соединения между таблицами. Они не оптимизируются с индексом из-за преобразования данных в соответствующих столбцах. Без индекса объединения становятся декартовыми объединениями, которые затем фильтруются путем оценки выражения объединения.

Зачем вам нужно преобразование на t1.idvisitor и t2.idvisitor? Изменение условий соединения просто

WHERE t1.idvisitor = t2.idvisitor 

поможет очень. То же самое с t3 и t4.

+0

Спасибо. Это и создание нового индекса для столбца location_ip помогло много. Теперь запрос компилирует отчет за 3 секунды. – nsilence

0

Попробуйте без conv (hex(),,).

Set @theDate = cast('2015-11-26 08:00:00' as datetime); SELECT t2.idorder AS 'Order ID', ( SELECT COALESCE(NULLIF(t3.referer_name,''), 'Direct') FROM piwik_log_visit t3 WHERE t3.idvisitor = t2.idvisitor AND t3.visit_first_action_time >= (@theDate - INTERVAL 32 DAY) ORDER BY t3.visit_last_action_time DESC limit 1 ) AS 'Referrer (Last)', ( SELECT COALESCE(NULLIF(t4.referer_name,''), 'Direct') FROM piwik_log_visit t4 WHERE t4.location_ip = t1.location_ip AND t4.visit_first_action_time >= (@theDate - INTERVAL 32 DAY) GROUP BY t4.location_ip ORDER BY t4.visit_first_action_time limit 1 ) AS 'Referrer (IP:First)', t1.referer_url AS 'Referrer URL' FROM piwik_log_visit t1, piwik_log_conversion t2 WHERE t1.idvisitor = t2.idvisitor AND t2.idorder IS NOT NULL AND t2.server_time BETWEEN '2015-11-25 07:59:59' AND '2015-11-26 08:00:00' AND t1.visit_first_action_time >= (@theDate - INTERVAL 32 DAY) GROUP BY t2.idorder

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