MySQL: эффективный блоббинг?

Я имею дело с большими двоичными объектами размером до 100 килобайт. Данные уже сжаты.

Механизм хранения: InnoDB на MySQL 5.1

Внешний интерфейс: PHP (Symfony с Propel ORM)

Некоторые вопросы:

  • Я где-то читал, что обновлять большие двоичные объекты нехорошо, потому что это приводит к перераспределению, фрагментации и, следовательно, к плохой производительности. Это правда? Любая ссылка на это?

  • Первоначально большие двоичные объекты создаются путем добавления фрагментов данных. Каждый фрагмент имеет размер до 16 килобайт. Будет ли более эффективно использовать вместо этого отдельную таблицу фрагментов, например, с полями, как показано ниже?

    parent_id, position, chunk

    Затем, чтобы получить весь BLOB-объект, нужно сделать что-то вроде:

    SELECT GROUP_CONCAT(chunk ORDER BY position) FROM chunks WHERE parent_id = 187

    Результат будет использоваться в PHP-скрипте.

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


person feklee    schedule 09.01.2011    source источник
comment
GROUP_CONCAT() не подходит для этого. По умолчанию максимальная длина ограничена 1024 байтами (хотя вы можете изменить это с помощью group_concat_max_len). Вы также должны быть очень осторожны при построении запроса - что произойдет, если фрагменты сгруппированы/объединены в неправильном порядке?   -  person Marc B    schedule 09.01.2011
comment
Я не вижу проблемы с лимитом, так как его можно продлить. Что касается получения конкатенации в правильном порядке: Вот почему я предлагаю поле position. Разве этого не должно быть достаточно?   -  person feklee    schedule 09.01.2011
comment
просто выберите каждый фрагмент и объедините их в PHP. или, если вы их выводите, выводите их вообще без объединения.   -  person araqnid    schedule 10.01.2011
comment
аракнид: Почему я должен это делать? В чем преимущество? Фактически, я предполагаю, что MySQL намного эффективнее для этого шага. Кстати, конкатенированный результат затем подвергается постобработке. Он не отправляется на экран.   -  person feklee    schedule 10.01.2011


Ответы (1)


Если вы создаете и удаляете данные в таблице, вы получите фрагментацию структуры данных таблицы.

Я не думаю, что вы можете что-то получить, разбивая большие двоичные объекты на куски — вы ничего не получаете, фрагментируя данные до того, как БД их фрагментирует :)

Вы можете дефрагментировать структуру таблицы, перестроив ее (OPTIMIZE TABLE в MySQL).

Я не смог найти информацию о том, как MySQL хранит большие двоичные объекты на диске. Если он хранит их вместе с другими данными строк, вы можете использовать кластеризованный индекс (PK в InnoDB, ALTER TABLE ORDER BY в MyISAM), чтобы требовать определенного порядка данных в файле данных таблицы (например, по популярности, чтобы создать «горячую» область, которая может улучшить кэширование и уменьшить немного ищу).

Помимо фрагментации собственной структуры базы данных существует проблема фрагментации файла таблицы в файловой системе.

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

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

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

Или вы можете просто использовать аппаратное обеспечение для решения проблемы — использовать RAID, добавить тонну оперативной памяти для кэшей дисков/БД или использовать SSD.

И, конечно же, вы тщательно сравнили его и знаете, что фрагментация — это прежде всего проблема, верно?

person Kornel    schedule 11.01.2011
comment
Фактически, я обнаружил, что на данный момент фрагментация не является проблемой. После введения сжатия большие двоичные объекты, как правило, становятся довольно маленькими (до пары килобайт), а операции добавления выполняются нечасто. Так что приоритеты немного изменились. Однако меня по-прежнему интересует разница между типами данных blob. Кроме того, я помню, как читал, что MySQL хранит большие BLOB-объекты в другом месте, чем маленькие BLOB-объекты, и что это гораздо менее эффективно. Это было бы еще одной причиной для использования отдельной таблицы чанков, помимо (да) фрагментации. Впрочем, на данный момент это не проблема. - person feklee; 12.01.2011