#sql #postgresql #performance #join #indexing
#sql #postgresql #Производительность #Присоединиться #индексирование
Вопрос:
Я хочу объединить две таблицы (таблица «продукты» содержит 1,5 миллиона записей), используя следующий запрос, но через 15 минут запрос все еще выполнялся, и мой компьютер перегревался (это lenovo v330-14ikb с 8 ГБ оперативной памяти), поэтому я остановил его.
Я очень новичок в индексах, и я попытался создать следующее:
- СОЗДАЙТЕ ИНДЕКС customer_id_idx1 ДЛЯ заказов (customer_id)
- СОЗДАЙТЕ ИНДЕКС customer_id_idx2 ДЛЯ продуктов (customer_id)
- СОЗДАЙТЕ ИНДЕКС customer_id_revenues_idx ДЛЯ заказов (customer_id, доходы)
- СОЗДАЙТЕ ИНДЕКС customer_id_costs_idx ДЛЯ продуктов (customer_id, затраты)
Это запрос:
SELECT a.customer_id, (SUM(a.revenues) / SUM(b.costs) :: FLOAT) AS roi
FROM orders a
JOIN products b
ON a.customer_id = b.customer_id
WHERE a.customer_id IN (
SELECT customer_id FROM (SELECT
customer_id,
COUNT(*) AS n_products
FROM products
GROUP BY 1
ORDER BY 2 DESC
LIMIT 5) x
)
GROUP BY a.customer_id
ORDER BY roi DESC
Выходные данные должны возвращать соотношение доходов / затрат для 5 лучших клиентов по количеству купленных ими продуктов.
Я использую pgadmin. Может кто-нибудь объяснить мне, как ускорить и заставить его скомпилироваться? Заранее благодарю вас.
Ответ №1:
Я не думаю, что вам нужно агрегировать дважды, насколько я могу судить.
select customer_id, roi
from (
select o.customer_id,
sum(o.revenues) / sum(p.costs)::float as roi,
count(*) as n_products
from orders o
join products p on o.customer_id = p.customer_id
group by o.customer_id
order by n_products
limit 5
) t
order by roi desc
В качестве альтернативы попробуйте объединить две таблицы по отдельности, а затем объединить результаты:
select o.customer_id, o.revenues / p.costs::numeric as roi
from (
select customer_id, sum(revenues) as revenues
from orders
group by customer_id
) o
join (
select customer_id, sum(costs) as costs, count(*) n_products
from products
group by customer_id
) p on p.customer_id = o.customer_id
order by p.n_products desc
limit 5