#performance #postgresql
#Производительность #postgresql
Вопрос:
недавно я установил PostgreSQL 9.0 с Postgis на компьютере с windows7. Затем я загрузил несколько таблиц в одну схему. Теперь я хочу выполнить очень простой запрос, и на данный момент я вижу, что это занимает более 10 минут. Я искал во многих местах, также в stackoverflow.com и до сих пор я могу понять, в чем моя ошибка.
моя проблема:
Tbl_Proprietarios — 230000 записей
Tbl_Predio — 160000 записей
SELECT id_predios
FROM "Tbl_Predio"
where id_predios not in
(
SELECT id_predios
FROM "Tbl_Proprietarios"
)
;
Спасибо
Комментарии:
1. Есть ли у вас индекс по
id_predios
столбцу в обеих таблицах?2. да, у меня есть (забыл сказать это)
3. Является ли тип данных id_predios одинаковым (предположительно целочисленным) в обеих таблицах?
Ответ №1:
Попробуйте левое внешнее соединение:
SELECT Tbl_Predio.id_predios
FROM Tbl_Predio
LEFT OUTER JOIN Tbl_Proprietarios ON Tbl_Predio.id_predios = Tbl_Proprietarios.id_predios
WHERE Tbl_Proprietarios.id_predios IS NULL;
Кроме того, убедитесь, что включен индекс Tbl_Proprietarios.id_predios
.
Ответ №2:
По моему опыту работы с SQL Server in
operator обычно работает очень медленно.
Обычно лучше exists
:
SELECT id_predios
FROM "Tbl_Predio"
WHERE not exists (
SELECT 1
FROM "Tbl_Proprietarios"
WHERE "Tbl_Proprietarios".id_predios = "Tbl_Predio".id_predios
)
(Обратите внимание, что в MySQL обычно происходит обратное, но логически зависит от выполняемого вами запроса)
Или вы можете использовать левое соединение:
SELECT id_predios
FROM "Tbl_Predio"
left join "Tbl_Proprietarios" on "Tbl_Proprietarios".id_predios = "Tbl_Predio".id_predios
WHERE "Tbl_Proprietarios".id_predios is null
Чтобы узнать, что происходит, используйте EXPLAIN.
Комментарии:
1. я не знаю, как, но оба ваших запроса выполняются быстро и …. я уже пытался использовать Exists и ОСТАВИЛ JOIN ….. после 2 дней на этом … лучше перекусить! Спасибо
Ответ №3:
Должен выполняться через несколько секунд на приличной машине. Определение таблицы? Индексы? план запроса? Конфигурация? Память?
SELECT id_predios
FROM Tbl_Predio t1
WHERE NOT EXISTS (
SELECT *
FROM Tbl_Proprietarios t2
WHERE t2.id_predios = t1.id_predios
)
;
Редактировать:
План запроса с записями 2 * 999 тыс.:
Hash Anti Join (cost=29813.47..61463.98 rows=79 width=4) (actual time=3470.658..7142.042 rows=1045 loops=1)
Hash Cond: (t1.id_predios = t2.id_predios)
-> Seq Scan on tbl_predio t1 (cost=0.00..13912.33 rows=999033 width=4) (actual time=0.038..1458.946 rows=999033 loops=1)
-> Hash (cost=13911.54..13911.54 rows=998954 width=4) (actual time=3238.919..3238.919 rows=998954 loops=1)
-> Seq Scan on tbl_proprietarios t2 (cost=0.00..13911.54 rows=998954 width=4) (actual time=0.057..1479.807 rows=998954 loops=1)
Total runtime: 7143.919 ms
(6 rows)
ПРАВКА2:
тестовый скрипт:
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp;
DROP TABLE tmp.Tbl_Predio CASCADE;
DROP TABLE tmp.Tbl_Proprietarios CASCADE;
CREATE TABLE tmp.Tbl_Predio ( id_predios INTEGER NOT NULL );
CREATE TABLE tmp.Tbl_Proprietarios ( id_predios INTEGER NOT NULL );
INSERT INTO tmp.Tbl_Predio ( id_predios) SELECT serie.val
FROM generate_series(1,1000000) AS serie(val)
;
INSERT INTO tmp.Tbl_Proprietarios ( id_predios) SELECT serie.val
FROM generate_series(1,1000000) AS serie(val)
;
DELETE FROM tmp.Tbl_Predio WHERE random() <= 0.001 ;
DELETE FROM tmp.Tbl_Proprietarios WHERE random() <= 0.001 ;
ALTER TABLE tmp.Tbl_Predio ADD PRIMARY KEY (id_predios) ;
ALTER TABLE tmp.Tbl_Proprietarios ADD PRIMARY KEY (id_predios) ;
EXPLAIN ANALYZE
SELECT id_predios
FROM tmp.Tbl_Predio t1
WHERE NOT EXISTS (
SELECT *
FROM tmp.Tbl_Proprietarios t2
WHERE t2.id_predios = t1.id_predios
)
;
Комментарии:
1. Ваше предложение по запросу также медленное: (
2. Какой флаг конфигурации я должен проверить?
3. Ваши определения таблиц и план запросов также медленные 🙂
4. Память (shared_buffers, effective_cache_size), файловые дескрипторы. Ваш диск — настоящий диск или сетевая вещь?
5. shared_buffers = 32 МБ? Этого достаточно, чтобы запустить службу базы данных… wiki.postgresql.org/wiki/Tuning_Your_PostgreSQL_Server и покажите нам результат ОБЪЯСНЕНИЯ