Правильный способ сделать сотни обновлений базы данных? - PullRequest
1 голос
/ 13 мая 2019

У меня есть функция, которая каждую минуту запрашивает Google BigQuery, и я хочу использовать результаты BigQuery для обновления строк в другой реляционной базе данных.

Я пытался сделать что-то вроде этого:

BEGIN TRANSACTION
    UPDATE MyTable SET MyField = BigQueryResult_Row1_MyField WHERE a_id = BigQueryResult_Row1_a_id
    UPDATE MyTable SET MyField = BigQueryResult_Row2_MyField WHERE a_id = BigQueryResult_Row2_a_id
    UPDATE MyTable SET MyField = BigQueryResult_Row3_MyField WHERE a_id = BigQueryResult_Row3_a_id
    .
    .
    .
    UPDATE MyTable SET MyField = BigQueryResult_RowN_MyField WHERE a_id = BigQueryResult_RowN_a_id
COMMIT TRANSACTION

Это оператор UPDATE для каждой строки большого запроса.Я не могу сделать один оператор UPDATE в сочетании с оператором SELECT, потому что данные поступают из BigQuery, а не из другой таблицы базы данных.

При попытке выполнить эту транзакцию я получаю сообщение об ошибке тайм-аута, поэтому я хочуСпросите: это правильный способ делать сотни обновлений одновременно?В некоторых случаях может быть даже тысячи обновлений одновременно.Как я могу сделать это лучше?

Ответы [ 2 ]

2 голосов
/ 13 мая 2019

Ответ Рената в порядке.Но более разговорный способ написания использует values():

UPDATE t 
        SET MyField = v.MyField       
    FROM MyTable t JOIN
         (VALUES ('BigQueryResult_Row1_MyField', 'BigQueryResult_Row1_a_id'),
                 ('BigQueryResult_Row2_MyField', 'BigQueryResult_Row2_a_id'),
                 ('BigQueryResult_Row3_MyField', 'BigQueryResult_Row3_a_id'),
                 ('BigQueryResult_RowN_MyField', 'BigQueryResult_RowN_a_id')
         ) v(MyField, a_id)
        ON v.a_id = t.a_id;

В общем, использование UNION, когда вы намереваетесь UNION ALL, является плохой идеей - потому что UNION влечет за собой накладные расходы на удаление дубликатов.В этом случае конструктор таблицы в любом случае является более простым решением.

0 голосов
/ 13 мая 2019

Работает ли такой запрос без тайм-аута (используя временную таблицу, как предложено @JohnHC)?

BEGIN TRANSACTION

;WITH UpdateTempTable AS (
    SELECT 'BigQueryResult_Row1_MyField' As MyField, 'BigQueryResult_Row1_a_id' AS a_id
    UNION SELECT 'BigQueryResult_Row2_MyField', 'BigQueryResult_Row2_a_id'
    UNION SELECT 'BigQueryResult_Row3_MyField', 'BigQueryResult_Row3_a_id'
    UNION SELECT 'BigQueryResult_RowN_MyField', 'BigQueryResult_RowN_a_id'
  ) UPDATE MyTable 
        SET MyTable.MyField = UpdateTempTable.MyField       
    FROM MyTable 
        JOIN UpdateTempTable ON UpdateTempTable.a_id = MyTable.a_id;

COMMIT TRANSACTION
...