#sql #amazon-redshift
#sql #amazon-redshift
Вопрос:
Я хочу получить все строки в таблице, где один столбец соответствует связи со значением столбца в строке в другой таблице, которая имеет то же значение другого столбца.
Конкретно, у меня есть две таблицы, orders и product_info, к которым я обращаюсь через Amazon Redshift
Заказы
| ID | Date | Amount | Region |
=====================================
| 1 | 2019/4/1 | $120 | A |
| 1 | 2019/4/4 | $100 | A |
| 2 | 2019/4/2 | $50 | A |
| 3 | 2019/4/6 | $70 | B |
Ключами порядка разделов являются регион и дата.
Информация о продукте
| ID | Release Date | Region |
| ---- | ------------ | ------ |
| 1 | 2019/4/2 | A |
| 2 | 2019/4/3 | A |
| 3 | 2019/4/5 | B |
Первичный ключ информации о продукте — id, а ключ раздела — region .
Я хочу получить все строки из заказов в регионе A, где дата строки больше, чем значение даты выпуска в информации о продукте для этого идентификатора.
Таким образом, в этом случае он должен возвращать только одну строку,
| 1 | 2019/4/4 | $100 | A |
Я попытался сделать
select *
from orders
INNER JOIN product_info ON orders.date>product_info.release_date
AND orders.id=product_info.id
AND orders.region=A
AND product_info.region=A
limit 10
Проблема в том, что этот запрос был абсурдно медленным (отменен через 10 минут). Таблицы очень большие, и у меня такое ощущение, что он сканировал всю таблицу, не ограничивая ее сначала регионом (на самом деле у меня есть другие фильтры в дополнение к region, которые я хочу применить к списку идентификаторов, прежде чем выполнять внутреннее объединение, но я ограничил его только регионом дляради упрощения вопроса).
Как я могу эффективно написать этот тип запроса?
Комментарии:
1. Можете ли вы добавить свои определения таблиц, чтобы мы могли видеть, какие индексы у вас есть, и план объяснения.
2. Не могли бы вы уточнить, используете ли вы MySQL или Amazon Redshift? Возможности и синтаксис различаются в зависимости от двух систем.
3. Отредактировал вопрос, чтобы показать, что я использую Amazon Redshift.
Ответ №1:
Лучший способ ускорить SQL-запрос — исключить строки как можно скорее.
Таким образом, вместо того, чтобы ставить условия, как orders.region=A
в инструкции JOIN, вы должны переместить их в WHERE
инструкцию. Это приведет к удалению строк до их объединения.
Кроме того, сделайте JOIN
условие как можно более простым, чтобы база данных могла оптимизировать сравнение.
Попробуйте что-то вроде этого:
SELECT *
FROM orders
INNER JOIN product_info ON orders.id = product_info.id
WHERE orders.region = 'A'
AND product_info.region = 'A'
AND orders.date > product_info.release_date
Любая дальнейшая оптимизация потребует рассмотрения DISTKEY
и SORTKEY
в таблицах Redshift. (Предпочтительно a DISTKEY
of id
и a SORTKEY
of date
).