Что быстрее, горизонтальный или вертикальный счет? - PullRequest
1 голос
/ 18 сентября 2010

Мне нужно получить сводные данные из множества строк. Сводные поля подсчитывают, сколько записей имеют каждое значение для разных полей. Например, в таблице с указанием возраста, города, места работы и т. Д. Итоговые данные будут включать такие поля, как «countManager», «countCodeMonkey» для каждой вакансии, а затем «countChicago», «countNewYork» и т. Д. Для городов.

Я знаю, что простой способ получить все это:

select count(*) from table
    group by age, city, job

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

| State | countManager | countMonkey |
|  IL   |      3       |     25      |
|  NY   |      5       |     40      |

Я смотрю на два способа сделать это. У нас уже есть один реализованный, и выполнение занимает 20 минут. Мне интересно, будет ли другой путь быстрее.

Текущий способ выглядит так:

create view managers as
    select state, count(*) as theCount from table
        where job = 'Manager'
        group by state;

create view monkeys as
    select state, count(*) as theCount from table
        where job = 'Monkey'
        group by state;

select managers.theCount as managers, monkeys.theCount as monkeys
    from managers left join monkeys
        on managers.state = monkeys.state;

В реальном случае есть еще около 20 просмотров и, следовательно, еще 20 соединений.

Вместо этого я рассматриваю следующий метод горизонтального подсчета:

select state,
  sum(case when job='Manager' then 1 else 0 end) as managers,
  sum(case when job='Monkey' then 1 else 0 end) as monkeys
    from table
        group by state;

Это исключает объединения. Но я не имею ни малейшего представления о выполнении заявления "сумма дела". Будет ли это быстрее, примерно так же или намного медленнее? Нужно ли двигателю проходить по строкам несколько раз, по одному разу для каждого такого подсчитанного поля? Или он достаточно умен, чтобы считать все поля за один проход, проверяя каждое значение и увеличивая соответствующую сумму?

Я могу потратить часть дня на написание сценария для генерации огромного количества мусорных данных, чтобы проверить это, но я все же хотел бы знать, как ведет себя механизм db, которого я не смог найти в другом месте в Интернете.

Ответы [ 2 ]

3 голосов
/ 18 сентября 2010

Полностью зависит от движка и того, как вы хотите видеть данные, но ваш второй вариант определенно должен работать быстрее.

20 минут даже для вашего первого запроса просто смешно, если только у вас нет буквально миллиардов строк,В этом случае вы должны смотреть на архивирование данных на ежемесячной / еженедельной основе с предварительно скомпилированными агрегированными данными в таблице, где вы можете нарезать их и нарезать кубиками.

1 голос
/ 18 сентября 2010

Если между вашей транзакцией и другими нет параллелизма, «сумма кейс» - хороший выбор. Агрегатные функции как AVG, SUM, GROUP BY, ухудшают производительность. Оставайтесь на связи с двумя вещами: «разделяй и властвуй» и «числовые данные быстрее, чем текстовые данные».

Создайте хранилище данных (отдельную таблицу, базу данных), чтобы избежать параллелизма и ускорить обработку.

CPU - великолепные калькуляторы: конвертируйте ваши категориальные данные ("NY", "LA", "Man", "Woman") в числовые данные (1, 2, 61, 62) и улучшить свою добычу.

Освободите свой разум от поставщиков баз данных или выбора платформ, но от алгебры отношений.

...