MySQL Performant запрос, чтобы сделать запрос подсчета в столбце каждой строки другого запроса - PullRequest
0 голосов
/ 16 мая 2009

У меня есть таблица с устройствами, их купленной страной и датой их покупки. Я хочу получить: - общее количество устройств по стране - и количество устройств, купленных с 1 месяца для каждой страны.

Я использую этот запрос, чтобы сделать это:

SELECT countryCode, COUNT(*) AS sinceBeginning, (
SELECT COUNT(*) 
FROM mytable 
WHERE countryCode = table1.countryCode
AND buyedDate >= DATE_SUB( CURDATE( ) , INTERVAL 1 MONTH )
) AS sinceOneMonth
FROM mytable AS table1
GROUP BY countryCode
ORDER BY countryCode ASC";

Но внутренний счетчик для столбца "SinceOneMonth" каждой строки очень дорог для производительности Есть ли способ сделать этот запрос лучше? Спасибо.

Ответы [ 3 ]

1 голос
/ 16 мая 2009

Ваша производительность, вероятно, улучшится с помощью составного индекса для кода страны и даты покупки, и если вы никогда напрямую не запросите дату покупки без передачи кода страны, то вы, вероятно, можете удалить индекс для кода страны и заменить его составным.

Следующий запрос может работать лучше, но не обязательно так, как всегда, от шаблонов ваших данных.

SELECT countrycode, 
       SUM(in_month) AS this_month, 
       COUNT(*)      AS all_time
FROM  ( 
         SELECT countrycode, 
                buyedDate >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH) AS in_month 
         FROM mytable
      ) AS summary 
GROUP BY countrycode;
0 голосов
/ 16 мая 2009

Спасибо, Стив и Андомар,

С запросом:

ВЫБЕРИТЕ код страны, COUNT (*) AS с начала, SUM (buyedDate> = DATE_SUB (CURDATE (), INTERVAL 1) МЕСЯЦ)) КАК С МЕСЯЦА ИЗ mytable ГДЕ модель = 1 GROUP BY код страны;

Производительность лучше: оригинальный запрос занимает 4 секунды, теперь 2 секунды. Результаты тестов: код страны с начала месяца 1 500101 20184 с 600.000 строк в таблице

0 голосов
/ 16 мая 2009

Есть ли индекс (код страны, buyedDate)?

РЕДАКТИРОВАТЬ: С запросом Стива Вита еще более упростил:

SELECT 
  countrycode
, SUM(buyedDate >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH)) AS this_month
, COUNT(*) AS all_time
FROM  mytable
GROUP BY countrycode
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...