хуйу нас не матерятся
Так получилось, что для текущего проекта требуется очень много и быстро считать SELECT COUNT. На этапе разработки не задумывались о том насколько быстро умеют это делать современные системы управления базами данных. Изначально мы использовали обычный MYSQL и innodb табличку, и пока в таблице хранилось меньше 100к строк, проблем никаких не было.
А начались проблемы когда количество данных увеличилось до 200к строк и пара юзеров увели сервер в 504ю. Ребут, конечно, спас, но немного погодя проблема вернулась. Начали разбираться и выяснили, что узким местом являются запросы SELECT COUNT. Проблема ещё и в том, что мы не можем использовать кэширование, потому что данные быстро обновляются, и нам нужна именно риалтайм статистика. Memory хранилище мы тоже не можем использовать, потому что в случае чп, результаты должны сохраниться + MYSQL memory engine не умеет в полнотекстовый поиск, а он нужен.
Как обычно, первое, что мы сделали- это заапгрейдили сервер, ровно в 2 раза, с 4 до 8Гб памяти, с 2 до 4 Ядер. А в результате получили скромные +100к строк, свыше которых опять начинаются проблемы. Тут мы и задумались, что нужно потестить что-то ещё.
Mysql - особый случай, так как у него есть 2 бд engine подходящие для нас- innodb и myisam. И хоть сами разработчики говорят, что будущее за innodb, протестировать myisam мы обязаны. Также в тест включили firebird, хоть у него и нет родного full-text поиска. Методика тестирования:
Перед началом очередного теста, очищаются все базы данных, затем:
Firebird и myisam в безусловных лидерах. Innodb и Postgre отстают как минимум в 2 раза. Но это не критично. Главное, что независимо от размера базы - время операции INSERT не меняется для всех бд.
А вот тут уже интересней. Innodb - отстаёт катастрофически. Причём есть явный прыжок в районе 25k строк. Возможно, именно это явление у нас и вешает сервер, но поскольку наш сервер в разы мощнее тестовой виртуалки за 5$, то проявляется это не на 25k а на 200k строк.
Далее идёт одинаковый результат для postgre и firebird, обычный линейный рост, как и должно быть. И внезапно результат myisam, не зависящий от количества записей в таблице.
Это очень неожиданно, и я сразу подумал, что myisam использует грязный чит, и держит какую-нибудь специальную переменную, в которой хранится количество строк в таблице, и по запросу SELECT COUNT(*) from table он не выполняет запрос, а просто выдаёт заранее известное значение.
Для того чтобы это проверить, я сделал повторный тест для myisam, только теперь добавил условие: SELECT COUNT(*) from table where anyprop=1 . Но результат получился точно такой же.
Для нашей задачи безусловный лидер myisam. И хоть в тесте он показал абсолютное безразличие к размеру таблицы, такого просто не может быть. Это значит, что мы использовали недостаточно большую таблицу, чтобы увидеть различия. Но надо помнить, что с транзакциями у myisam большие проблемы.
Innodb- безусловный аутсайдер. Нет никаких причин его использовать для подобных задач. Если нужна стабильная и быстрая субд с поддержкой транзакций, используйте postgre или firebird.