Как оптимизировать совокупный SQL? - PullRequest
2 голосов
/ 04 августа 2011

Предположим схему таблицы, например:

name amount_1, amount_2, cond_1, cond_2

в таблице 500 000 + строк.

Как оптимизировать запрос, например:

select 
  name
  , sum(amount_1) as total_1
  , sum(amount_2) as total_2
  , sum(amount_1+amount_2) as total 
from table_name 
where cond_1 in ('a', 'b') 
group by name 
order by total desc 
limit 10;

Текущий sql займет несколько минут.

Ответы [ 4 ]

2 голосов
/ 04 августа 2011

Вероятно, вам не хватает индексов в этих столбцах:

  • name для группировки
  • cond_1 для фильтрации

Если вы предпочитаете иметь только составной индекс, я рекомендую сделать индекс на (cond_1, name) (не наоборот).Зачем?cond_1 должен быть первым столбцом в составном индексе, поскольку предикат фильтра может получить прибыль только от столбцов слева от индекса.

Это объясняется здесь, например: http://use -the-index-luke.com/sql/where-clause/the-equals-operator/concatenated-keys

1 голос
/ 04 августа 2011

Индексация поможет, плюс вы можете слегка переписать запрос:

SELECT
  s.*, s.total_1 + s.total_2 AS total
FROM (
  SELECT
    name
    , SUM(amount_1) as total_1
    , SUM(amount_2) as total_2
  FROM table_name 
  WHERE cond_1 in ('a', 'b') 
  GROUP BY name ) s
ORDER BY total DESC 
LIMIT 10;

Это предотвратит сумму (total_1 + total_2) по всем строкам, но вместо этого повторно использует итоговые значения, рассчитанные в total_1 и total_2.

Вы также можете попробовать этот вариант, который может быть медленнее или быстрее: -).
Если у вас есть индекс на сумму 1 и количество 2, а существенная, но не огромная доля равна 0, это может быть намного быстрее.

SELECT
  s.*, s.total_1 + s.total_2 AS total
FROM (
  SELECT
    name
    , SUM(amount_1) as total_1
    , SUM(amount_2) as total_2
  FROM table_name 
  WHERE cond_1 in ('a', 'b') AND (amount_1 <> 0 AND amount_2 <> 0)
  GROUP BY name ) s
ORDER BY total DESC 
LIMIT 10;

Если у вас есть много вещей в IN, возможно, это будет быстрее

WHERE cond_1 BETWEEN 'a' AND 'z'

Это обменивает 26 тестов ИЛИ на 2 И тесты.

0 голосов
/ 19 марта 2013

, если это важная часть вашего бизнеса, учитывая OLAP, это более быстрый способ, чем я знаю

0 голосов
/ 04 августа 2011

За исключением индексов, упомянутых Лукасом Эдером, я предполагаю, что один из sum не нужен, потому что если amount_1 и amount_2 равны NOT NULL, то у вас будет уравнение

total = total_1+ total_2

Итак, если вам нужно total для оформления заказа, вы можете потерять total_2 и рассчитать его после выполнения запроса как (total - total_1)

Не знаю, сильно ли это вас спасетвремя, но выглядит как небольшая оптимизация для меня.

...