Как рассчитать размер оператора MySQL (не результаты запроса)

Я работаю над инструментом, который генерирует и запускает SQL для базы данных MySQL. Я пытаюсь добавить возможность ограничения размера оператора вставки на основе заданного пользователем параметра. Я нашел некоторую информацию о max_allowed_packet настройки, но я не нашел ничего, что объясняет, как рассчитать размер пакета. Документы MySQL говорят, что "коммуникационный пакет - это отдельный оператор SQL, отправляемый на сервер MySQL", но я не понимаю, как определяется размер оператора SQL.

Я передаю инструкцию SQL и некоторые параметры моему драйверу:

cmd.CommandText= "INSERT INTO myTable VALUES(@int, @date, @text)";
cmd.Parameters.AddWithValue("@int", 1);
cmd.Parameters.AddWithValue("@date", DateTime.Now);
cmd.Parameters.AddWithValue("@text", "how big is this???");
cmd.ExecuteNonQuery();

Является ли размер пакета просто суммой байтов, используемых в строковом представлении всех переменных и оператора SQL? Или я должен выяснить размер каждого параметра на основе того, сколько места они будут занимать в базе данных, и суммировать это с байтами, используемыми в строке SQL? Или что-то другое? Я не совсем уверен, как работают драйверы баз данных, так что, может быть, какой-то контекст будет полезен, если вы что-нибудь о них знаете

2 ответа

Решение

Оказывается, что max_allowed_packet сравнивается с размером результирующего запроса, который был отправлен по проводам в кодировке ASCII. Я просто вложил значения параметров в оператор SQL вместо имен параметров и взял размер результирующей строки. Количество байтов было точным прогнозом того, будет ли MySQL отклонять оператор, поэтому я мог выяснить, когда начинать новый оператор на основе этого числа.

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

Вы должны увеличить значение [max_packet_allowed], если вы используете большие BLOB-столбцы или длинные строки. Он должен быть таким же большим, как самый большой BLOB, который вы хотите использовать. Ограничение протокола для max_allowed_packet составляет 1 ГБ. Значение должно быть кратно 1024; немножки округляются до ближайшего кратного.

Приведенная выше цитата взята из документации v5.5 по адресу https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html.

Из выражения "он должен быть таким же большим, как самый большой BLOB, который вы хотите использовать", я заключаю, что max_packet_size основан на размере столбца, а не на размере оператора sql. Размер данных столбца будет зависеть от содержимого и кодировки. Проверьте набор символов и параметры сортировки, чтобы выяснить, используете ли вы 2-байтовый или 4-байтовый символ.

Простой способ проверить, является ли это размером оператора или размером столбца, состоит в том, чтобы иметь простую таблицу с двумя текстовыми столбцами. Предположим, ваш max_packet_allowed составляет 16 МБ как на клиенте, так и на сервере. Запустите оператор вставки, где один из столбцов равен 8M, а другой - 10M (всего 18M). Если оператор не выполняется, это размер оператора. Если это не сбои, вы можете предположить, что это зависит от размера столбца.

Поскольку вы реализуете проверку размера пакета с помощью max_packet_allowed, важно помнить, что ОБА серверу и клиенту установлено это значение. И тот, который ниже, является реальным максимумом. Поскольку клиент может установить его, вы не можете предполагать, что они всегда одинаковы.

Я с радостью отредактирую этот ответ, если для правильной информации будут предоставлены дополнительные ссылки. И если я далеко от базы, я с удовольствием удалю ответ.

Другие вопросы по тегам