Оптимизировать SQL-запрос для отчета - PullRequest
1 голос
/ 28 июля 2011

Это SQL-запрос, который я написал, он работает нормально, но медленно.

SELECT D.Username, 
        SUM(CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END) as Yes, 
        SUM(CASE WHEN D.type = 'No' THEN 1 ELSE 0 END) as No, 
        SUM(CASE WHEN D.type = '' THEN 1 ELSE 0 END) as Other, 
        SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales, 
        COUNT(*) as TOTAL FROM dairy as D
  LEFT JOIN (SELECT DISTINCT mobile FROM sales) as S on D.MobileNo = S.mobile 
        WHERE source = 'Network' AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1309561200
 group by D.Username order by TOTAL DESC

Как видите, подсчитайте количество продаж Да, Нет, Другое и соответствующую продажу MobileNo (D.MobileNo = S.mobile).

Я попытался добавить индекс к типу, имени пользователя, мобильному телефону, MobileNO, CheckDate и источнику - производительность не сильно улучшилась.

Ответы [ 2 ]

2 голосов
/ 28 июля 2011

Три вопроса, на которые следует обратить внимание в вашем запросе:

1.Существует вероятность того, что `LEFT JOIN` вызовет проблемы с производительностью.

Однако вам это нужно, поскольку вполне возможно, что D.MobileNo значений не будет присутствовать в SELECT DISTINCT mobile FROM sales.Любой другой обходной путь (да, есть варианты), скорее всего, снизит производительность.Но ваша производительность может быть улучшена при наблюдении следующих пунктов.

2.Убедитесь, что у вас есть индексы в ключевых столбцах:

  • D.type
  • S.mobile
  • D.MobileNo
  • D.Username
  • D.Source
  • D.CheckDate

3.У вас могут быть проблемы с фильтрацией по `UNIX_TIMESTAMP (CheckDate)`

Это может быть ключевой проблемой.У вас могут возникнуть проблемы с фильтрацией по UNIX_TIMESTAMP(CheckDate) вместо CheckDate, особенно если Dairy имеет большое количество записей.Проблема в том, что даже если у вас есть индекс для CheckDate, он, вероятно, не будет использоваться из-за функции.Попробуйте отфильтровать по CheckDate.

0 голосов
/ 28 июля 2011

Если это критично ко времени, также имеет смысл хранить больше данных.

Здесь это означает, что вы добавляете столбцы INT для YesValue, NoValue, OtherValue и заполняете их 0 или 1 в своем приложении. Делая это, вы можете удалить расчеты кейса из вашей части SELECT.

Также, пожалуйста, опубликуйте все доступные в настоящее время индексы, а в комментариях укажите CREATE-оператор для таблицы.

...