Что быстрее: сумма (случай, когда) Или группа по / Count(*)?

#sql #count #sum

#sql #подсчитывать #сумма

Вопрос:

Я могу написать

 Select 
Sum(Case When Resposta.Tecla = 1 Then 1 Else 0 End) Valor1,
Sum(Case When Resposta.Tecla = 2 Then 1 Else 0 End) Valor2,
Sum(Case When Resposta.Tecla = 3 Then 1 Else 0 End) Valor3,
Sum(Case When Resposta.Tecla = 4 Then 1 Else 0 End) Valor4,
Sum(Case When Resposta.Tecla = 5 Then 1 Else 0 End) Valor5
From Resposta
  

Или

 Select 
    Count(*)
From Resposta Group By Tecla
  

Я попробовал это для большого количества строк, и, похоже, это заняло столько же времени.

Кто-нибудь может это подтвердить?

Ответ №1:

Я считаю, что Group By лучше, потому что нет конкретных методов лечения. Это может быть оптимизировано ядром базы данных. Я думаю, что результаты могут зависеть от используемого вами ядра базы данных. Возможно, тот, который вы используете, оптимизирует первый запрос и понимает, что это похоже на group by !

Вы можете попробовать команду «explain / план объяснения», чтобы увидеть, как движок вычисляет ваши запросы, но с моим Microsoft SQL Server 2008 я просто вижу обмен между 2 операциями («Вычислить скалярный» и «агрегировать»).

Я пробовал такие запросы в таблице базы данных :

  • SQL Server 2k8
  • 163000 строк в таблице
  • 12 категорий (Valor1 -> Valor12)

результаты совершенно разные :

  • Группировка по: 2 секунды
  • Случай, когда: 6 секунд!

Итак, мой выбор — «Group By». Еще одним преимуществом является то, что запрос проще писать!

Ответ №2:

То, что БД делает внутренне со вторым запросом, практически совпадает с тем, что вы явно указываете ему делать с первым. Не должно быть никакой разницы в плане выполнения и, следовательно, во времени, которое занимает запрос. Принимая это во внимание, очевидно, что лучше использовать второй запрос:

  • это намного более гибко, когда есть больше значений Tecla , вам не нужно изменять свой запрос
  • это легче понять. Если у вас много значений для Tecla , будет сложнее прочитать первый запрос и понять, что он просто учитывает разные значения
  • это меньше — вы отправляете меньше информации на сервер БД, и он, вероятно, быстрее обработает запрос, что является единственной разницей в производительности, которую я вижу в этих запросах. Это имеет значение, хотя и небольшое

Ответ №3:

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

Я бы обычно использовал:

 Select
    Tecla,
    Count(*)
From Resposta
Group By Tecla
  

Если есть разумная вероятность, что диапазон Tecla значений изменится в будущем.

Ответ №4:

На мой взгляд, GROUP BY оператор всегда будет быстрее, чем SUM(CASE WHEN ...) потому что в вашем примере для SUM ... было бы 5 разных вычислений, в то время как при использовании GROUP BY DB будет просто сортировать и вычислять.

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

  • SUM(CASE WHEN ...) Способ состоял бы в том, чтобы сравнить каждую монету с предопределенными образцами монет и выполнить математические вычисления для каждого образца (добавить 1 или 0).;
  • GROUP BY Способом было бы отсортировать монеты по их типам, а затем подсчитать каждую группу поиска.

Какой метод вы бы предпочли?

Ответ №5:

Чтобы честно конкурировать с count(*) , ваш первый SQL, вероятно, должен быть:

 Select 
Sum(Case When Resposta.Tecla >= 1 AND Resposta.Tecla <=5 Then 1 Else 0 End) Valor
From Resposta
  

И чтобы ответить на ваш вопрос, я вообще не замечаю разницы в скорости между SUM CASE WHEN и COUNT . Я запрашиваю более 250 000 строк в POSTGRESQL.