Транзакция MySQL с тысячами вставок - сколько нужно «циклов»? - PullRequest
9 голосов
/ 21 сентября 2008

У меня есть код C #, который обращается к MySQL через ODBC.

Создает транзакцию, выполняет несколько тысяч команд вставки, а затем фиксирует. Теперь у меня вопрос: сколько «обходов», так сказать, происходит с сервером БД? Я имею в виду, он просто передает каждую команду вставки на сервер БД, или он кэширует / буферизует их и отправляет их в пакетном режиме? И это настраивается каким-либо образом?

Ответы [ 8 ]

18 голосов
/ 21 сентября 2008

MySQL имеет расширенный стиль SQL, который можно использовать, когда массовые вставки вставляются по несколько одновременно:

INSERT INTO `table` (`id`, `event`)  VALUES (1, 94263), (2, 75015), (3, 75015);

Обычно я собираю несколько сотен частей вставки в строку перед выполнением самого запроса SQL. Это уменьшит накладные расходы на синтаксический анализ и обмен данными, выполняя их самостоятельно.

4 голосов
/ 30 декабря 2010

Нет ограничений на количество строк как таковых; Ограничение на количество байтов, переданных на сервер.

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

2 голосов
/ 21 сентября 2008

Обратный путь к серверу БД - это не то же самое, что обратный путь к базе данных на диске.

Прежде чем вы решите, что поездки являются узким местом, сделайте некоторые реальные измерения.

Существуют способы вставки нескольких строк за одну вставку, в зависимости от вашей СУБД. Прежде чем вкладывать средства в кодирование, выясните, может ли это принести вам пользу.

2 голосов
/ 21 сентября 2008

Выполняется один запрос в оба конца на каждый отправленный вами запрос (независимо от того, находится ли он в транзакции или нет).

В MySQL можно использовать синтаксис «расширенной вставки», который позволяет вставлять несколько (или даже много) строк в одну инструкцию. Обычно это считается хорошим делом.

0 голосов
/ 20 декабря 2013

Предел данных, которые будут отправлены, зависит от вашего сервера, поэтому максимальная длина нескольких операторов вставки автоматически подстраивается под размер. Узким местом является длина пакета и длина буфера.

См. Описания переменных net_buffer_length и max_allowed_packet для получения дополнительной информации:

https://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_net_buffer_length https://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_max_allowed_packet

В некоторых случаях вы можете настроить их (например, при выгрузке данных), чтобы не создавать вставки, которые слишком длинные, но сохраняют несколько вставок. Имейте в виду, что если в ваших таблицах есть некоторые большие двоичные объекты или другие длинные значения, которые могут превышать значения упомянутых переменных, вы можете получить ошибки или неполные данные.

0 голосов
/ 29 июля 2009

Это зависит от того, где вы вызываете оператор SQL. Я попробовал это однажды с драйвером MySQL JDBC и получил ошибку, говоря, что ограничение составляет 1 МБ, но это настраивается

Я не стал его настраивать, а просто разбил операторы SQL на более мелкие части.

0 голосов
/ 21 сентября 2008

При использовании MySQL 4.x несколько лет назад мы столкнулись с жестким ограничением размера запроса, которое нельзя было настроить.

Это, вероятно, вам не очень поможет, так как:

  1. Я не помню, какой был жесткий предел.
  2. Вы, вероятно, не используете MySQL 4.x.
  3. Мы не использовали транзакции.

Удачи!

0 голосов
/ 21 сентября 2008

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

В MSSql вы можете выполнить несколько вставок в одном выражении:

cmd.ExecuteNonQuery "insert table values (1)  insert table values (2)"

Таким образом, вы можете создать большую строку и выполнить ее (я думаю, что у нее будет ограничение), я предполагаю, что это будет работать для MySQL.

Также в MSSQL у вас есть пакетный инсертор (поиск «SqlBulkCopy»), в MySQL возможно попробуйте загрузка данных из временного файла .

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