Блог


Выбор движка БД. InnoDB vs MyISAM.

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



История эта началась примерно в 2005 году, когда учитывая недостатки существующих СУБД был разработан движок InnoDB, а особенно когда его поддержку начал осуществлять MySQL.

Революционным отличием InnoDB стало отношение к целостности данных. Этот движок начал поддерживать транзакции и внешние ключи, а так же блокировку на уровне строк, что оказалось решающим оружием в холиварах MyISAM vs InnoDB. Разумеется, ради надежности можно пожертвовать многим, и скоростью, и занимаемым местом, и еще некоторыми моментами. Однако холивары хоть и утихли, давайте все же попробуем разобраться, совсем ли помер MyISAM на сегодняшний день.


Сначала давайте разберемся, как устроено хранение данных в этих двух движках. Как в MyISAM, так и в InnoDB, данные хранятся в файлах. Различие в том, что MyISAM для каждой таблицы создает свой файл, InnoDB по умолчанию все хранит в общем. Кроме того, InnoDB поддерживает MVCC, так называемую "мультиверсионность". Это значит, что каждый пользователь работает со своим "экземпляром" БД, не мешая другим. Всё это ведет к увеличению размера хранилища, что не может не сказаться на производительности. Вот эти два момента и были основным оружием тех, кто выступал за приоритетность MyISAM. Дело в том, что последний и действительно выигрывает в некоторых случаях, но именно из-за того, что в силу своей структуры не поддерживает транзакций.


Впрочем как не крути, а надежность важнее. Кроме того, блокировка таблиц в InnoDB происходит на уровне рядов таблицы, в отличие от MyISAM, где таблица блокируется полностью. И при правильной архитектуре и расстановке индексов проигрыш по скорости первого можно свести к нулю, а иногда даже вывести в плюс. А значит медленно и верно все начали переходить на InnoDB. Ваш покорный слуга кстати тоже.

Однако есть моменты, когда без MyISAM еще достаточно сложно обойтись. Один из важных моментов - InnoDB не поддерживает индекс FULLTEXT, а значит на нем сложнее организовать полнотекстовый поиск. И хотя с версии MySQL 5.6.4 его включили в InnoDB, пока эта версия доступна не везде.

Где еще можно использовать MyISAM. В тех случаях, когда таблицы не изменяются или изменяются достаточно редко. Допустим в справочниках, индексации контента, хранении книг и так далее. Другими словами там, где СУБД используется для чтения, а не модификации информации. Тут размер хранилища и скорость выборки может оказаться существенным критерием. А целостности данных ничего не угрожает.

Еще прироста в производительности за счет снижения накладных расходов можно добиться при использовании MyISAM в организации небольших "горячих" таблиц, в которых целостность данных не столь критична. Допустим в счетчиках посетителей он-лайн к примеру. Там, где таблица невелика, выигрыш на блокировке рядов против блокировки всей таблицы незначителен, а проигрыш на инсертах ощутим. MyISAM, что ни говори, все же больше оптимизирован для операций INSERT, особенно при больших потоках. При большой посещаемости это может оказаться важным. А опасность разрушения данных не столь критична, они актуальны несколько минут.

Не очень хорошо себя ведет InnoDB по сравнению с MyISAM при подсчете строк функцией COUNT(*). Последний хранит количество строк отдельно, и получить его можно очень быстро. InnoDB для этого перебирает всю таблицу. Это тоже может оказаться полезным при выборе статических данных, для постраничного режима допустим. Но это касается полной выборки, без клаузы WHERE. Если есть условие, скорости уравниваются, так как MyISAM тоже вынужден считать строки.

Резюмируя - InnoDB приоритетнее там, где важна целостность данных. При использовании транзакций и внешних ключей база данных становится более монолитной, исчезает опасность фантомных записей или прерванных операций. А целостность данных важна везде, где есть модификация. Запись/обновление/удаление. Там где этих операций нет, MyISAM может оказаться предпочтительнее по скорости выборки. Выгоднее по производительности MyISAM может оказаться при массированных инсертах, однако опять же есть опасность "поломки", что почти всегда важнее скорости.

Еще есть важный момент, чрезмерное увлечение плюсами иногда приводит к большому минусу. Дел в том, что при использовании транзакций немудрено нарваться на так называемый deadlock, "блокировка насмерть". Что совершенно невозможно в MyISAM.

Ну а в основном конечно MyISAM сдает позиции развивающемуся в нужном направлении InnoDB, начиная с 5.5 версии MySQL MyISAM утратил лидерство и InnoDB стал дефолтным. Оно и к лучшему, если правильно его использовать, он позволяет качественно решить почти любую задачу.

Это не значит, что нужно сломя голову перестраивать рабочие проекты, миграция на InnoDB не так проста, как кажется. Но при выборе движка для нового приложения нужно взвесить все за и против. Как обычно, все хорошо на своем месте. И зачастую лучше смириться с некоторыми маленькими минусиками ради многих больших жирных плюсов. Это касается обоих движков.

Надеюсь, что после моего опуса выбрать будет немного легче. 

 

Николай aka twin
Теги: MySQL

Комментарии (7)

akuchkovsky
23-09-2013
Я как буд-то по пятам иду))
Вчера как раз читал этут статью про таблицы в Битрикс, может тоже кому-то будет интересно
ссылка
akuchkovsky
23-09-2013
Сделайте пожалуйста возможно редактировать комменты, а то поблагодарить забыл Вас за хорошее объяснение, вас я лучше понимаю, нужно второй коммент писать, неудобно)
Сергей
27-11-2013

цитата:
Не очень хорошо себя ведет InnoDB по сравнению с MyISAM при подсчете строк функцией COUNT


Запустите данный запрос на большом количестве данных и увидите что InnoDB, в 2 раза быстрее считает строки.
twin
28-11-2013
Имелось ввиду COUNT(*), именно со звездочкой. Внес поправку, дабы небыло разночтений. Такой опертор в MyISAM работет намного быстрее, ибо этот двиг хранит количество строк в заголовке, а InnoDB в любом случе перебирает строки. Повторюсь, это касается только тех запросов, где нет условий.
Сергей
27-11-2013
и не клауза, а клаузула
twin
28-11-2013
Не соглашусь. Хотя и используются оба определения, клаузула на мой взгляд как раз ошибочное. Ибо клауза, это просто часть предложения (запроса), их в нем может быть несколько. Клаузула во-первых бывет только одна (это завершающая часть), во-вторых, так как она завершающая, после неё не может быть ничего. А после WHERE может спокойно ставится LIMIT или ORDER к примеру. Так что под определение "звершающая часть" или "клаузула" WHERE никак не подходит.

 
Наверх