2012-01-07 3 views
0

У меня есть две таблицы. Один из них - это журнал кликов, который записывает точное время, которое мы получили. Второй - это таблица за доллар/день, в которой записывается сумма, которую мы заработали каждый день с определенного сайта.speed up mysql query

Мне нужно рассчитать ежедневную цену за клик для каждого сайта. Запрос ниже работает, но занимает почти минуту.

Вот результат объяснить:

id select_type  table   type possible_keys  key  key_len  ref  rows  Extra 
1 SIMPLE   click_log  ALL  url_id,click_time NULL NULL  NULL 1404209 Using where; Using temporary; Using filesort 
1 SIMPLE   daily_dollars ref  url_id,date   date 3   func 6   Using where 

И запрос:

SELECT date(click_log.click_time) AS DAY, 
     click_log.shorturl AS site, 
     daily_dollars.money AS earned, 
     count(click_log.click_id) AS clicks, 
     daily_dollars.money/count(click_log.click_id) AS CPC 
FROM `yourls_log` AS click_log, yourls_url_money AS daily_dollars 
WHERE click_log.click_time >= "2011-07-01" 
    AND click_log.url_id = daily_dollars.url_id 
    AND date(click_log.click_time) = daily_dollars.date 
GROUP BY DAY , click_log.shorturl 

Все, что я могу сделать, чтобы ускорить этот процесс?

Структура таблицы:

yourls_log 
---------- 
click_id 
click_time 
shorturl 
url_id 

yourls_url_money 
---------------- 
id 
url_id 
date 
money 
+2

Не могли бы вы опубликовать структуру таблицы? –

+0

Я не достаточно хорош в MySQL, чтобы предлагать советы о том, как ускорить ваш запрос, но то, что я делаю, рекомендую вам [использовать явный метод 'JOIN'] (http://mysqljoin.com/). – Bojangles

+0

Это GROUP BY замедляет запрос, потому что он не может использовать индекс. Если нет конкретных причин для этого, попробуйте удалить GROUP BY. Кстати, из вашего запроса 'DAY' ссылается на' click_log'.'click_time', и поскольку время может сильно различаться между записями, я не вижу причин для группировки на 'DAY', нет? – Abhay

ответ

0

Не знаю, почему, но это намного быстрее (1,5 секунды):

SELECT m.date, c.shorturl, m.money, c.clicks, m.money/c.clicks AS CPC 
FROM yourls_url_money AS m 
LEFT JOIN (

SELECT date(click_time) AS 
DAY , url_id, shorturl, count(click_id) AS clicks 
FROM yourls_log 
WHERE click_time >= "2011-07-01" 
GROUP BY DAY , url_id, shorturl 
) AS c ON m.url_id = c.url_id 
AND m.date = c.day 
WHERE date >= "2011-07-01" 
0

Если вы создали представление под СУБД, а затем запросить мнение, этот процесс должен завершить наделите быстрее. В основном это связано с тем, что представление - это данные, которые уже были собраны, а не запрашивать данные со смещения.

Также смотрите на статистику своего сервера, возможно, при слишком большой нагрузке?

+0

Спасибо, хотя сервер и mysql хорошо оптимизированы. Я считаю, что файл-сортировка там, где проблема – Eric

0

Я думаю, что это то, что вы хотите:

SELECT DISTINCT date(click_log.click_time) AS DAY, 
    click_log.shorturl AS site, 
    daily_dollars.money AS earned, 
    count(click_log.click_id) AS clicks, 
    daily_dollars.money/count(click_log.click_id) AS CPC 
FROM `yourls_log` AS click_log, yourls_url_money AS daily_dollars 
WHERE click_log.click_time >= "2011-07-01" 
AND click_log.url_id = daily_dollars.url_id 
AND date(click_log.click_time) = daily_dollars.date 
ORDER BY DAY , click_log.shorturl 
+0

Спасибо, хотя это возвращает только одну строку ... Мне нужно общее для каждой комбинации день/сайт. – Eric