2016-09-30 3 views
1

У меня есть две таблицы:Оптимизация SQL запросов на таблицу 10 миллионов строк: Бесконечная запроса

CREATE TABLE routing 
(
    id integer NOT NULL, 
    link_geom geometry, 
    source integer, 
    target integer, 
    traveltime_min double precision, 
    CONSTRAINT routing_pkey PRIMARY KEY (id) 
) 
    WITH (
    OIDS=FALSE 
); 

CREATE INDEX routing_id_idx 
    ON routing 
    USING btree 
    (id); 

CREATE INDEX routing_link_geom_gidx 
ON routing 
USING gist 
(link_geom); 

CREATE INDEX routing_source_idx 
ON routing 
USING btree 
(source); 

CREATE INDEX routing_target_idx 
ON routing 
USING btree 
(target); 

и

CREATE TABLE test 
(
link_id character varying, 
link_geom geometry, 
id integer NOT NULL, 
.. (some more attributes here) 
traveltime_min double precision, 
CONSTRAINT id PRIMARY KEY (id), 
CONSTRAINT test_link_id_key UNIQUE (link_id) 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE test 
OWNER TO postgres; 

и я пытаюсь Апи в follwing запрос:

update routing 
set traveltime_min = t2.traveltime_min 
from test t2 
where t2.id = routing.id 

Обе таблицы имеют около 10 миллионов строк. Проблема в том, что этот запрос работает бесконечно. Вот что показывает «EXPLAIN»:

Update on routing (cost=601725.94..1804772.15 rows=9712264 width=208) 
-> Hash Join (cost=601725.94..1804772.15 rows=9712264 width=208) 
     Hash Cond: (routing.id = t2.id)" 
     -> Seq Scan on routing (cost=0.00..366200.23 rows=9798223 width=194)" 
     -> Hash (cost=423414.64..423414.64 rows=9712264 width=18)" 
      -> Seq Scan on test t2 (cost=0.00..423414.64 rows=9712264 width=18)" 

Я не могу понять, что может вызвать проблему такого медленного ответа. Возможно ли быть проблемой, вызванной настройками сервера? Дело в том, что я использую настройки postgrSQL 9.3 по умолчанию.

+0

Добро пожаловать в SO. Если вам нужен какой-то советник DBA, возможно, лучше спросить свой вопрос здесь: http://dba.stackexchange.com/ Но вы тоже получите ответы на это сообщение, я думаю, – swe

+0

Возможно, ваше обновление ждет блокировки? Вы это проверили? https://wiki.postgresql.org/wiki/Lock_Monitoring –

ответ

0

Перед тем, как запустить UPDATE, добавьте их еще раз. Это значительно улучшит ситуацию.

Установить work_mem высоко в сессии, где вы запускаете UPDATE. Это поможет с хешем.
Комплект shared_buffers to & frac14; доступной памяти, но не более 1 ГБ.

+0

'work_mem' = 1024kB и 'shared_buffers' = 16384, как я вижу из pg_settings. Я не хочу менять значения конфигурации, потому что в прошлом это вызывало у меня дополнительные проблемы. Но спасибо. Я дам ему попробовать. – CorneliaS

+0

Да, оставьте эти настройки. Но попробуйте без индексов. –

0
  • Если не все строки фактически изменены UPDATE (если они получают то же значение, что и у них), вы должны избегать этих идемпотентных обновлений.
  • Если вы ожидаете, что запрос повлияет на каждую строку, план запроса не имеет значения. [За исключением, может быть, в случае отказа хэш-таблицы ...]

-- these could be needed if the update would be more selective... 
VACUUM analyze routing; 
VACUUM analyze test; 

UPDATE routing dst 
SET traveltime_min = src.traveltime_min 
FROM test src 
WHERE dst.id = src.id 
    -- avoid useless updates and row-versions 
AND dst.traveltime_min IS DISTINCT FROM src.traveltime_min 
    ; 

-- VACUUM analyze routing; 
+0

все строки будут обновлены. Фактически я создал новый столбец в таблице маршрутизации, и я хочу передать все значения из другой таблицы, где идентификаторы столбцов одинаковы. – CorneliaS

+0

В этом случае СУБД придется обрабатывать 9M строк * 200 байт. Примерно три раза, так как исходная страница + новые версии строк должны быть записаны (переписаны). Это около 6 ГБ дискового трафика. – joop

Смежные вопросы