В какой БД лучше хранить данные связей такого вида entity_id + [another_entity_id, ..., another_entity_id]?
Привет, сейчас использую таблицу для связи сущностей на MySQL MyIsam.
Структура наипростейшая: entity_id, another_entity_id
+ 2 индекса: entity_id + another_entity_id (уникальный) и another_entity_id + entity_id
К таблице используются запросы:
1) Выбрать все another_entity_id по entity_id = X
2) Выбрать все entity_id по another_entity_id = Y
3) COUNT по вышеприведённым выборкам
4) Возможно какие-то аналитические запросы по пересечению айдишников
На каждый entity_id может приходиться до 10млн another_entity_id.
В принципе запросы отрабатывают быстро, но при 300млн записях сами данные занимают 4гб + индексы (!!!) 11 гб.
Стоит задача сократить занимаемое место при сохранении или даже с увеличением производительности.
Первым пришло в голову использовать документно-ориентированные БД.
1) MongoDB отвалился сразу, т.к. имеет физическое ограничение на размер одного BSON документа в 16мб, что хватает только на документ вида: entity_id + [массив 1 млн another_entity_id]. Производительность и размер данных в результате такой подставы оценить не удалось.
2) PostgreSQL и тип jsonb может хранить документы любого размера, также имеет возможность поиска по документу, GIN индексы занимающие гораздо меньше места, но производительность поиска по jsonb отвратительно медленная. Видимо нужно ждать релиза индексов типа VODKA. А так же очень медленные инсёрты. Небольшая экономия жёсткого диска.
2.1) PostgreSQL и массив интов (integer[]) по производительности сопоставим с поиском по jsonb, но более быстрые инсёрты.
Пока что получается, что MyIsam уделывает всех по производительности. Что посоветуете, комрады?
Возьмите PostGRE, а структуру оставьте такой же.
С индексами у вас что-то напутано - по сути 2 одинаковых индекса, думаете СУБД сама не догадается поменять местами поля при необходимости?
Я бы сделал уникальный кластерный индекс по entity_id + another_entity_id, и отдельные дополнительные индексы по каждому полю.
Попробуйте для начала на MySQL с индексами разобраться - место освободится. Может на этом и остановитесь.
Для увеличения производительности - переносите базу на SSD носитель.
Они у вас строковые?
Нафиг строки - заведите 2 справочника для entity и another_entity, в каждом справочнике числовой уникальный ID, а вашу таблицу переделайте на использование чисел.
konchober: "Мускул не умеет использовать индекс entity_id + another_entity_id для запросов" для этого я и посоветовал 2 индекса по отдельности для каждого поля. В итоге вместо 2 индексов по 2 поля, будет 2 индекса по 1 полю. Кластерный индекс места занимает гораздо меньше. Освободите примерно половину пространства, занимаемого сейчас индексами.