Структура базы данных и путаница во времени поиска на жестком диске

StackOverflow https://stackoverflow.com/questions/600400

  •  03-07-2019
  •  | 
  •  

Вопрос

может ли кто-нибудь помочь мне, пытаясь понять, как работает поиск на жестком диске?

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

Если среднее время поиска на жестком диске составляет 10 мс, а скорость чтения - 300 МБ / с, я подсчитал, что функция read() работает быстрее, чем функция seek () со значением меньше 3 МБ.Это правда?Есть ли накладные расходы при выполнении нового поиска, которых нет при чтении существующего потока?

Какая, по вашему мнению, файловая структура более подходит для индекса?

Entry1:Value:PointerIntoToData
Entry2:Value:PointerIntoToData
Entry3:Value:PointerIntoToData
Data, Data, Data

Or

Entry1:Value:Data
Entry2:Value:Data
Entry3:Value:Data

При чтении записи, если значение неверно, оно будет проигнорировано.Итак, при потоковой передаче файла быстрее ли:1.если запись не требуется, используйте функцию seek(), чтобы пропустить ее 2.если запись не нужна, прочтите ее, а затем выбросьте данные 3.или структура use first, когда требуется запись seek() в хранилище данных в конце.

Размер записи - 4 байта, значения - 8 байт, а данных - 12 КБ

Ваше здоровье

Это было полезно?

Решение

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

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


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


Если ваша база данных слишком велика:

Данные считываются и записываются на физический диск блоками (или страницами).Аналогично, основной единицей ввода-вывода с диска в вашей операционной системе является страница.Если операционная система кэширует данные с диска, то это также происходит на целых страницах.Поэтому думать о том, нужно ли вам переместить вперед несколько байтов, используя seek или read, не имеет особого смысла.Если вы хотите сделать это быстро, вам нужно принять во внимание, как на самом деле работает дисковый ввод-вывод.

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

Что касается структуры данных для индекса.Как правило, они организованы следующим образом B-деревья.Это структура данных, созданная специально для эффективного поиска больших объемов данных, хранящихся в памяти, с помощью постраничного чтения и записи.

И обе стратегии организации данных используются на практике.Например, MS SQL Server по умолчанию хранит данные первым способом:данные хранятся отдельно, и индексы содержат только данные из индексированных столбцов и физические адреса строк данных в файлах.Но если вы определите кластеризованный индекс, то все данные будут храниться внутри этого индекса.Все остальные индексы будут указывать на данные через кластеризованный индексный ключ вместо физического адреса.Первый способ проще, но другой может быть гораздо эффективнее, если вы часто выполняете сканирование диапазонов данных на основе кластеризованного индекса.

Другие советы

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

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

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

Последовательное чтение всегда выполняется быстрее, чем чтение, требующее поиска по заголовку (не по позиции).Типичная производительность жесткого диска для последовательного чтения составляет 50-60 МБ / с, что снижает ее до наихудшего показателя ~ 0,4 МБ / с.Как только приводные головки установлены, вы, по сути, получаете данные в цилиндре бесплатно.Кэш файловой системы использует это преимущество, предварительно считывая сектора из цилиндра.

Однако вы не имеете никакого контроля над размещением ваших данных на дисковых цилиндрах.Вы также не можете угадать геометрию привода.Обратите внимание, что пропускная способность может значительно ухудшиться со временем, когда объем становится фрагментированным.Вам нужно будет искать perf путем кэширования данных в памяти.В этот момент вы беспокоитесь о исходная местность.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top