#database #batch-file #insert #scalability
Вопрос:
Я создаю базу данных, сначала создаю прототипы и провожу сравнительный анализ. Я использую H2, базу данных java с открытым исходным кодом, коммерчески бесплатную, встраиваемую, реляционную. В настоящее время я не индексирую ни один столбец.
После того, как база данных выросла примерно до 5 ГБ, скорость пакетной записи удвоилась (скорость записи была замедлена в 2 раза по сравнению с первоначальной скоростью). Я писал примерно 25 строк в миллисекунды со свежей, чистой базой данных, и теперь при 7 ГБ я пишу примерно 7 строк в мс. Мои строки состоят из короткого, int, с плавающей точкой и байта[5].
Я мало что знаю о внутренних компонентах базы данных или даже о том, как был запрограммирован H2. Я также хотел бы отметить, что я не ругаю H2, так как это проблема с другими СУБД, которые я тестировал.
Какие факторы могут замедлить работу базы данных подобным образом, если нет накладных расходов на индексирование? Имеет ли это в основном какое-то отношение к структуре файловой системы? Исходя из моих результатов, я предполагаю, что способ обработки файлов Windows XP и ntfs замедляет добавление данных в конец файла по мере его роста.
Ответ №1:
Одним из факторов, который может усложнить вставки по мере роста базы данных, является количество индексов в таблице и глубина этих индексов, если они являются B-деревьями или аналогичными. Просто нужно сделать больше работы, и может случиться так, что вы заставляете узлы индекса разделяться, или вы, возможно, просто перешли, скажем, с 5-уровневого B-дерева на 6-уровневое (или, в более общем плане, с N на N 1 уровни).
Другим фактором может быть использование дискового пространства-если вы используете готовые файлы (это нормально для большинства людей большую часть времени; некоторые СУБД используют «необработанные файлы» в Unix, но маловероятно, что ваша встроенная система сделает это, и вы бы знали, если бы это было так, потому что вам пришлось бы сказать ей об этом), возможно, ваши большие таблицы теперь фрагментированы по диску, что приводит к снижению производительности.
Если проблема заключалась в производительности SELECT, на производительность вашей системы также могло повлиять множество других факторов.
Комментарии:
1. интересно, я не думал, что файл будет фрагментирован по всему диску, но я полагаю, что так и должно быть, если он такой большой!
Ответ №2:
Это звучит примерно правильно. Производительность базы данных обычно значительно снижается, так как данные больше не могут храниться в памяти, а операции привязываются к диску. Если вы используете обычные операции вставки и хотите значительного повышения производительности, я предлагаю использовать какой-то API массовой загрузки, если его поддерживает H2 (например, Oracle sqlldr, Sybase BCP, Mysql «загрузка файла данных»). Этот тип API записывает данные непосредственно в файл данных, минуя многие подсистемы базы данных.
Ответ №3:
Скорее всего, это вызвано полями переменной ширины. Я не знаю, позволяет ли это H2, но в MySQL вы должны создать свою таблицу со всеми полями фиксированной ширины, а затем явно объявить ее как таблицу полей фиксированной ширины. Это позволяет MySQL точно рассчитать, куда ему нужно перейти в файле базы данных для выполнения вставки. Если вы не используете таблицу фиксированной ширины, то она должна прочитать таблицу, чтобы найти конец последней строки.
Добавление данных (если все сделано правильно) — это операция O(n), где n-длина записываемых данных. Это не зависит от длины файла, есть операции поиска, которые можно легко пропустить.
Комментарии:
1. Я забыл упомянуть, что мое поле byte[5] на самом деле находится в поле blob (поле переменной длины). Возможно, это как-то связано с этим. Спасибо вам всем за ваши быстрые ответы.
Ответ №4:
Для большинства баз данных добавление в файл базы данных определенно происходит медленнее, чем предварительное расширение файла с последующим добавлением строк. Посмотрите, поддерживает ли H2 предварительное расширение файла.
Комментарии:
1. Независимо от того, является ли это проблемой или нет, похоже, было бы неплохо предварительно вырастить ее. Спасибо!
Ответ №5:
Другая причина заключается в том, хранится ли вся база данных в памяти или операционной системе приходится много менять местами диски, чтобы найти место для хранения записи.
Ответ №6:
Я бы обвинил в этом ввод-вывод, особенно если вы запускаете свою базу данных на обычном ПК с обычным жестким диском (под этим я подразумеваю не сервер с супер быстрыми жесткими дисками и т. Д.).
Ответ №7:
Многие механизмы баз данных создают неявный целочисленный первичный ключ для каждого обновления, поэтому, даже если вы не объявили никаких индексов, ваша таблица все равно индексируется. Это может быть одним из факторов.
Ответ №8:
Использование H2 для файла данных 7G является неправильным выбором с технологической точки зрения. Как вы сказали, встраиваемый. Какое у вас «встроенное» приложение, если вам нужно хранить так много данных.
Ответ №9:
Выполняете ли вы инкрементные коммиты? Поскольку H2 является базой данных, совместимой с ACID, если вы не выполняете инкрементные фиксации, то существует некоторый тип журнала повторов, чтобы в случае какого-либо случайного сбоя (скажем, отключения питания) или отката удаления можно было откатить.
В этом случае ваш журнал повтора может увеличиваться и переполнять буферы памяти, и вам потребуется записать журнал повтора на диск, а также ваши фактические данные, что увеличит накладные расходы на ввод-вывод.