ОБНОВЛЕНИЕ SQL с объединенными таблицами: Ошибка нехватки памяти - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь обновить таблицу в pSQL и получаю всевозможные ошибки памяти / выполнения.

Странно то, что запрос SELECT для обновления очень быстрый. Я уверен, что просто не понимаю, что происходит под капотом.

Некоторый контекст.


Соответствующие таблицы

address_book:
loan_id,
county,
zip
---
loan:
id
---
loan_property:
loan_id,
property_id
---
property:
id,
zip,
county

Цель

Цель состоит в том, чтобы обновить zip & county таблицы свойств значениями в address_book. В address_book есть loan_id, который является соединением со свойством.


SQL

Давайте посмотрим на простой SELECT

WITH ab AS (
SELECT DISTINCT
    left(ab.loan_id, 6) AS loan_id,
    ab.zip AS zip,
    ab.county AS county
FROM 
    address_book ab
WHERE
    ab.address IS NOT NULL
)

SELECT ab.county, p.name

FROM property p
INNER JOIN loan_property lp ON lp.property_id = p.id
INNER JOIN loan           l ON lp.loan_id     = l.id
INNER JOIN               ab ON ab.loan_id     = l.id
WHERE 
    l.id = ab.loan_id

Это работает отлично и очень быстро (.4 сек. На ~ 10 тыс. Записей)

Давайте возьмем вышеприведенное и сделаем вызов UPDATE:

WITH ab AS (
SELECT DISTINCT
    left(ab.loan_id, 6) AS loan_id,
    ab.zip AS zip,
    ab.county AS county
FROM 
    address_book ab
WHERE
    ab.address IS NOT NULL
)

UPDATE property
SET zip=ab.zip, county=ab.county

FROM property p
INNER JOIN loan_property lp ON lp.property_id = p.id
INNER JOIN loan           l ON lp.loan_id     = l.id
INNER JOIN               ab ON ab.loan_id     = l.id
WHERE 
    l.id = ab.loan_id

Это обновление выполняется в течение 2 минут, а затем, как правило, происходит сбой на основе

Ошибка SQL [53200]: ОШИБКА: недостаточно памяти

Есть ли более оптимальный способ запустить это обновление? Даже если мне нужно выполнить пакетную обработку по LIMIT / OFFSET или сохранить результаты SELECT в таблице, а затем выполнить ОБНОВЛЕНИЕ непосредственно из этой таблицы - какой способ запустить это обновление без ошибок памяти?

Спасибо всем большое!

Ответы [ 4 ]

0 голосов
/ 11 января 2019

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

      WITH xyz AS (
      Select zip,property from property p
    INNER JOIN loan_property lp ON lp.property_id = p.id
     INNER JOIN loan           l ON lp.loan_id     = l.id
        INNER JOIN               ab ON ab.loan_id     = l.id
   WHERE 
    l.id = ab.loan_id group by some_value/order by zip)

    UPDATE xyz
     SET zip=ab.zip, county=ab.county
0 голосов
/ 11 января 2019

Как документировано в руководстве делать не повторить таблицу назначения в инструкции UPDATE:

...
UPDATE property
   SET zip = ab.zip, 
       county = ab.county
FROM loan_property lp
   JOIN loan l ON lp.loan_id = l.id
   JOIN ab ON ab.loan_id = l.id
WHERE lp.property_id = p.id
0 голосов
/ 11 января 2019

Я думаю, что мой ответ похож на ответ от @a_horse_with_no_name - что-то странное в повторной ссылке на целевую таблицу.

Я фактически объединил предложение FROM в обновлении в другой псевдоним вызова SELECT, например:

WITH ab as (
SELECT distinct
    p.id as p_id, 
    ab.county as county, 
    ab.zip as zip
FROM 
    address_book ab
inner join loan l on ab.loan_id = l.id
inner join loan_property lp on loan_id = l.id
inner join property p on lp.property_id = p.id
WHERE
    ab.address IS NOT null
    and l.id = ab.loan_id
)

UPDATE property
SET county__c=ab.county, zip_code__c=ab.zip
FROM ab
WHERE ab.p_id = id

Разделение соединений (особенно с целевой таблицей) из вызова FROM в обновлении устранило проблему.

0 голосов
/ 11 января 2019

Я предполагаю, что у вас есть недвижимость с большим количеством кредитов. Run:

select property_id, count(*)
from loan_property
group by property_id
order by count(*) desc;

Вопрос в том, с какой информацией вы хотите заполнить информацию.

Также возможно, что у вас есть кредиты со многими адресами. select distinct подозрительно там.

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