Как оптимизировать хранение строковых индексов
Раньше занимался обработкой больших объемов информации из сети на слабом оборудовании. И хочется сказать об оптимизации строковых индексов без привнесения дополнительных технических решений в проект. Чтоб было с цифрами - на серверах по $5-10 крутились реляционные базы с сотнями гигабайт индексированной информации. Лет 6 назад использовались сервера на пару ядер и 256-512 Мб оперативки. С тех пор научился ужимать индексы на порядки.
Индексирования строк создает большие индексы. Если хочется обойтись базовой базой, но нужно сделать индекс по строке, например, чтоб искать дубликаты, то для сокращения размера индекса разумно индексировать только начало строки. PostgreSQL, например, поддерживает такое, правда при таком подходе падает селективность индекса.
Альтернативный путь - индексировать дополнительный столбец char(32) содержащий md5-преобразование строки. Тем не менее, результат md5-преобразования занимает 32 байта на каждую строку, что тоже затратно. md5 - это набор из 32-х 16-ричных цифр, охватывающие пространство в 2^256 или больше чем 10^38. Но для большинства задач хватает намного меньшего диапазона значений. Например, сокращение char(32) до char(16) экономит 50% размера ключа, а значит и индекса. Но в 16 байтах хранится 16 символов или 16 8-ричных цифр, которые кодируют 8 байт информации. А значит это заменяется на bigint без потерь. Чтоб сделать это - сначала получить md5 строки, далее обрезать полученный хеш до 16 символов, затем выполнить преобразование из 16-ричной системы счисления в 10-тичную:text_index = conv(substring(md5(url), 1, 16), 16, 10);
Значения идентификаторов, полученные так, имеют также равномерное распределением по 8-байтовому пространству. Это обеспечивает достаточную селективность. В жертву конечно будут принесены операции LIKE и другие подобные.
Разумеется если нет проблем с железом, то такие хаки лучше заменить другими подходящими инструментами. Кстати, если вы знаете альтернативные подходы - поделитесь в комментариях.
>>Click here to continue<<