PostgreSQL ON vs WHERE при объединении таблиц? - PullRequest
0 голосов
/ 23 мая 2018

У меня есть 2 таблицы customer и coupons, клиент может иметь или не иметь назначенный reward_id, так что это столбец, который можно обнулять.У клиента может быть много купонов, а купон принадлежит клиенту.

+-------------+------------+
|   coupons   | customers  |
+-------------+------------+
| id          | id         |
| customer_id | first_name |
| code        | reward_id  |
+-------------+------------+
customer_id column is indexed

Я хотел бы объединить 2 таблицы.

Моя попытка:

select c.*, cust.id as cust_id, cust.first_name as cust_name
from coupons c
join customer cust
on c.customer_id = cust.id and cust.reward_id is not null

Тем не менее, я думаю, что нет индекса reward_id, поэтому мне нужно переместить cust.reward_id is not null в where предложение:

select c.*, cust.id as cust_id, cust.first_name as cust_name
from coupons c
join customer cust
on c.customer_id = cust.id
where cust.reward_id is not null

Интересно, будет ли вторая попытка более эффективной, чем первая?попытка.

1 Ответ

0 голосов
/ 23 мая 2018

Было бы лучше, если бы вы видели план выполнения самостоятельно.Добавьте EXPLAIN ANALYZE перед оператором select и выполните оба, чтобы увидеть различия.

Вот как:

EXPLAIN ANALYZE select ...

Что это делает?Он фактически выполняет оператор выбора и возвращает план выполнения, который был выбран оптимизатором запросов.Без ключевого слова ANALYZE он будет только оценивать план выполнения без фактического выполнения оператора в фоновом режиме.

База данных не будет использовать два индекса одновременно, поэтому наличие индекса на customer(id) сделает его неспособнымиспользовать индекс на customer(reward_id).Это условие будет фактически рассматриваться как условие фильтра, которое является правильным поведением.

Вы можете поэкспериментировать с производительностью частичного индекса, созданного так: customer(id) where reward_id is not null.Это уменьшит размер индекса, поскольку будет хранить только те идентификаторы клиентов, для которых назначен reward_id.

Я обычно хотел бы отделить логику взаимосвязи / соединения от примененных условий, и я сам помещал их в WHERE, потому что он более заметен и легче читается на будущее, если есть какие-либо изменения.

Я предлагаю вам самим убедиться в возможном выигрыше в производительности, потому что это зависит от объема данных и возможной низкой мощности для reward_id.Например, если в большинстве строк этот столбец заполнен значением, это не будет иметь большого значения, так как размер индекса (обычный или частичный) будет почти одинаковым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...