#mysql #performance
#mysql #Производительность
Вопрос:
Я создавал API для веб-сайта, и объекты, которые я ищу, имеют МНОГО полей true / false. Вместо создания огромной структуры БД для управления параметрами я подумал о сериализации их в строке, подобной ‘001001000010101001’, где 1 равно true, а 0 равно false (я говорю о 100 различных параметрах). Другая причина, по которой я это делаю, заключается в том, чтобы иметь чистую базу данных, чтобы все эти поля были сгруппированы в одно поле (у меня уже есть сериализатор / десериализатор).
Теперь в функции поиска, поскольку не все параметры ищутся одновременно, я думал об использовании оператора LIKE с подстановочными знаками.
Например, я бы сделал что-то вроде этого:
WHERE options LIKE '1_1__1__1___1%'
(Последний подстановочный знак заключается в уменьшении количества _ подстановочных знаков, чтобы совпадало только начало шаблона. Я бы остановился на последних проверенных параметрах для проверки и % wildcard для остальных).
Будет ли это (в среднем, потому что иногда может быть выбрано 2 или 3 параметра, и много раз могут быть выбраны все из них) более производительным, чем несколько серий И ХХХ И ХХХ И ….?
Или есть более эффективный (и простой в обслуживании) способ сделать это, который я полностью упускаю?
Ответ №1:
Позвольте мне обсудить некоторые из поднятых вами вопросов.
Я понимаю подход 0/1. Я нахожу интересным, что вы предпочли использовать строки вместо чисел. Для значения до 64 true / false подойдет BIGINT
(8 байт) или что-то меньшее.
Вы также хотели проверить наличие false для некоторых флагов? Ваш струнный механизм делает это довольно очевидным. (Ваш пример должен включать 0
.)
Поиск с помощью LIKE
будет эффективным только, если нет ведущего подстановочного знака ( _
или %
). Итак, я бы ожидал, что большинство ваших запросов будут включать полное сканирование таблицы. Ваш сериализатор плюс b
префикс будут работать для установки строк.
Целочисленный подход, с которым я сталкиваюсь, будет включать amp;
и другие логические операции для тестирования. Вероятно, это было бы заметно быстрее. Для этого потребуется полное сканирование таблицы.
Если в WHERE
предложении тестируются другие столбцы, давайте посмотрим на них. Они будут важны для производительности и индексации.
Использование чисел вместо строк было бы немного быстрее из-за меньшего размера и более быстрого тестирования. Но не сильно.
Вы можете получить некоторые преимущества numeric, используя SET
тип данных. (Снова ограничено 64 независимыми флагами на столбец.) Преимущество заключается в том, что вы общаетесь с базой данных через строки, а не зашифрованные позиции битов.
Если это приложение для недвижимости, рассмотрите несколько столбцов, таких как: kitchen
, bedrooms
, unusual_items
(вторая посудомоечная машина, джакузи) и т.д. Независимо от того, как это реализовано (строка, целое число, НАБОР), это предложение не сильно повлияет на производительность.
Еще одно замечание о производительности, опять же с моделью недвижимости: поскольку #bedrooms почти всегда является критерием, сделайте его отдельным столбцом. Это может позволить использовать его в составном индексе.