Что лучше, один «вставить выбор-объединение» (один запрос) или выбрать, а затем вставить (два запроса) - PullRequest
0 голосов
/ 16 октября 2019

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

Схема теста:

CREATE TABLE map (
   internalId INT NOT NULL,
   ownerId INT NOT NULL,
   PRIMARY KEY (internalId),
   INDEX (ownerId) 
);

Create Table content (
  internalId INT NOT NULL,
  contentId INT NOT NULL,
  PRIMARY KEY (internalId, contentId)
 );

INSERT INTO map (internalId, ownerId) VALUES (1,100), (2,1000)

Вариант 1: выбрать соответствующие строки на карте, а затем построитьвставить запрос. Вариант 2: работает следующий запрос (внутренние операторы выбора с UNION ALL генерируются программно):

INSERT IGNORE INTO content (SELECT internalId, contentId FROM (SELECT 101 AS contentId, 100 AS ownerId UNION ALL
     SELECT 102 AS contentId, 100 AS ownerId UNION ALL
     SELECT 103 AS contentId, 100 AS ownerId UNION ALL
     SELECT 1001 AS contentId, 1000 AS ownerId) AS s_q
     INNER JOIN map USING (ownerId));

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

1 Ответ

0 голосов
/ 16 октября 2019

Используйте один запрос.

Причина не в «производительности», «простоте» или «стиле» (хотя один запрос выигрывает по всем показателям) ... это целостность данных .

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

Один запрос всегда имеет правильный эффект.

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

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