Использование временной таблицы для замены предложения WHERE IN - PullRequest
2 голосов
/ 12 мая 2011

У меня есть пользователь, вводящий список значений, к которым мне нужно запросить в таблице. Список может быть потенциально очень большим, а длина неизвестна во время компиляции. Вместо того, чтобы использовать WHERE ... IN (...), я подумал, что было бы эффективнее использовать временную таблицу и выполнить соединение с ней. Я прочитал это предложение в другом вопросе SO (не могу найти его в данный момент, но буду редактировать, когда я это сделаю).

Суть что-то вроде:

CREATE TEMP TABLE my_temp_table (name varchar(160) NOT NULL PRIMARY KEY);

INSERT INTO my_temp_table VALUES ('hello');
INSERT INTO my_temp_table VALUES ('world');
//... etc

SELECT f.* FROM foo f INNER JOIN my_temp_table t ON f.name = t.name;

DROP TABLE my_temp_table;

Если бы два из них работали одновременно, я не получил бы ошибку, если поток 2 пытается создать таблицу TEMP после потока 1?

Должен ли я случайно генерировать имя для таблицы TEMP вместо этого?

Или, если я заверну все это в транзакции, исчезнет ли конфликт имен?

Это Postgresql 8.2.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 12 мая 2011

Нет необходимости беспокоиться о конфликте.

Схема pg_temp зависит от сессии. Если у вас есть параллельный оператор в отдельном сеансе, он будет использовать другую схему (даже если вы видите его с тем же именем).

Две ноты, однако:

  1. Каждый раз, когда вы создаете временные объекты, системный каталог создает временную схему и сами объекты. Это может привести к беспорядку при частом использовании.

    Таким образом, для небольших наборов / частого использования обычно лучше придерживаться оператора in или with (с которым Postgres справляется довольно хорошо). Также иногда полезно «обмануть» планировщика, используя тот план, который вы ищете, используя функцию возврата неизменяемого набора.

  2. Если вы решили использовать временные таблицы, обычно лучше их проиндексировать и проанализировать, как только вы их заполните. В противном случае вы делаете чуть больше, чем пишете with заявление.

2 голосов
/ 12 мая 2011

Рассмотрите возможность использования запроса WITH: http://www.postgresql.org/docs/9.0/interactive/queries-with.html

Также создается временная таблица, которая уничтожается при завершении запроса / транзакции, поэтому я считаю, что не должно быть конфликтов параллелизма.

...