Mysql
 sql >> база данни >  >> RDS >> Mysql

Производителност на MySQL:MyISAM срещу InnoDB

Основен фактор за производителността на базата данни е механизмът за съхранение, използван от базата данни, и по-конкретно, нейните таблици. Различните двигатели за съхранение осигуряват по-добра производителност в една ситуация спрямо друга. За общо ползване има двама претенденти, които трябва да бъдат взети предвид. Това са MyISAM, който е по подразбиране MySQL механизъм за съхранение, или InnoDB, който е алтернативен двигател, вграден в MySQL, предназначен за високопроизводителни бази данни. Преди да разберем разликата между двете системи за съхранение, трябва да разберем термина „заключване“.

Какво е заключването в MySQL?

За да защити целостта на данните, съхранявани в базите данни, MySQL използва заключване. Заключването, просто казано, означава защита на данните от достъп. Когато се приложи заключване, данните не могат да бъдат променени освен чрез заявката, която е инициирала заключването. Заключването е необходим компонент за гарантиране на точността на съхраняваната информация. Всеки механизъм за съхранение има различен използван метод на заключване. В зависимост от вашите данни и практики за заявки, една машина може да превъзхожда друга. В тази серия ще разгледаме двата най-често срещани типа заключване, използвани от нашите два двигателя за съхранение.

Заключване на масата: Техниката за заключване на цяла таблица, когато една или повече клетки в таблицата трябва да бъдат актуализирани или изтрити. Заключването на таблицата е методът по подразбиране, използван от механизма за съхранение по подразбиране MyISAM.

Пример:MyISAM Заключване на таблица Колона A Колона B Колона C
Запитване 1 АКТУАЛИЗИРАНЕ Ред 1 Писане данни данни
Заявка 2 SELECT (Изчакайте) Ред 2 данни данни данни
Заявка 3 АКТУАЛИЗИРАНЕ (Изчакайте) Ред 3 данни данни данни
Заявка 4 SELECT (Изчакайте) Ред 4 данни данни данни
Запитване 5 SELECT (Изчакайте) Ред 5 данни данни данни
Примерът илюстрира как една операция на запис заключва цялата таблица, карайки други заявки да чакат завършването на заявката UPDATE.

Заключване на ниво ред: Актът на заключване на ефективен диапазон от редове в таблица, докато една или повече клетки в рамките на диапазона се променят или изтриват. Заключването на ниво ред е методът, използван от InnoDB механизма за съхранение и е предназначен за високопроизводителни бази данни.

Пример:InnoDB заключване на ниво ред Колона A Колона A Колона A
Запитване 1 АКТУАЛИЗИРАНЕ Ред 1 Писане данни данни
Заявка 2 SELECT Ред 2 Четене данни данни
Актуализиране на заявка 3 Ред 3 данни Писане данни
Заявка 4 SELECT Ред 4 Четене Четене Четене
Заявка 5 SELECT Ред 5 Четене данни Четене
Примерът показва как използването на заключване на ниво ред позволява да се изпълняват множество заявки на отделни редове, като се заключват само актуализираните редове вместо цялата таблица.

MyISAM срещу InnoDB

Сравнявайки двата механизма за съхранение, стигаме до същността на спора между използването на InnoDB над MyISAM. Приложение или уебсайт, който има често използвана таблица, работи изключително добре, използвайки механизма за съхранение на InnoDB, като разрешава тесните места при заключване на таблицата. Въпреки това, въпросът за използването на един върху друг е субективен, тъй като нито един от тях не е перфектен във всички ситуации. Има силни страни и ограничения и за двата механизма за съхранение. Задълбочените познания за структурата на базата данни и практиките за заявки са от решаващо значение за избора на най-добрата машина за съхранение за вашите таблици.

MyISAM ще превъзхожда InnoDB на големи таблици, които изискват значително повече активност при четене спрямо записване. Четимостта на MyISAM засенчва InnoDB, защото заключването на цялата таблица е по-бързо, отколкото да разберете кои редове са заключени в таблицата. Колкото повече информация е в таблицата, толкова повече време отнема на InnoDB, за да разбере кои от тях не са достъпни. Ако приложението ви разчита на огромни таблици, които не променят често данните, тогава MyISAM ще превъзхожда InnoDB. Обратно, InnoDB превъзхожда MyISAM, когато данните в таблицата се променят често. Таблицата променя данните за запис повече, отколкото за четене на данни в секунда. В тези ситуации InnoDB може да се справи с големи количества заявки по-лесно, отколкото да заключва цялата таблица за всяка една.

Трябва ли да използвам InnoDB със сайтове на WordPress, Magento или Joomla?

Краткият отговор тук е да, в повечето случаи. Най-полезните хора на Liquid Web в екипите за поддръжка на хостинг са се сблъскали с няколко тесни места при заключване на таблици, когато клиентите използват някои стандартни уеб приложения днес. Повечето потребители на популярни приложения на трети страни като WordPress, Magento и Joomla имат ограничени познания за основните компоненти или код на базата данни, за да вземат информирано решение относно механизмите за съхранение. Повечето тесни места при заключване на таблици от тези системи за управление на съдържанието (CMS) обикновено се разрешават чрез промяна на всички таблици за сайта на  InnoDB вместо MyISAM по подразбиране. Ако хоствате много от тези типове CMS на вашия сървър, би било полезно да промените механизма за съхранение по подразбиране в MySQL, за да използвате InnoDB за всички нови таблици, така че всяка нова инсталация на таблици да започва с InnoDB.

Задаване на машината за съхранение по подразбиране

Задайте вашата машина за съхранение по подразбиране на InnoDB, като добавите default_storage_engine=InnoDB към [mysqld] раздел на системния конфигурационен файл, намиращ се на адрес: /etc/my.cnf. Рестартирането на услугата MySQL е необходимо, за да може сървърът да открие промени във файла.

~ $ cat /etc/my.cnf
[mysqld]
log-error=/var/lib/mysql/mysql.err
innodb_file_per_table=1
default-storage-engine=innodb
innodb_buffer_pool_size=128M

Конвертиране на всички таблици между MyISAM и InnoDB

За съжаление MySQL по своята същност няма опция за конвертиране на таблици, оставяйки всяка таблица да се променя поотделно. Екипът за поддръжка на Liquid Web е съставил лесен за следване план за поддръжка за този процес. Скриптът, който можете да стартирате на необходимия сървър чрез shell access (SSH), ще преобразува всички таблици между системи за съхранение.

Забележка Планирайте съответно, когато извършвате пакетни операции от това естество, само в случай, че възникне престой. Най-добрата практика е да архивирате всичките си MySQL бази данни, преди да приложите промяна от този мащаб, като по този начин осигурявате лесна точка за възстановяване, за да предотвратите загуба на данни.

Стъпка 1:  Подготовка

Планирайте да започнете по време на деня, когато престоят ще има минимални последици. Този процес сам по себе си не изисква престой, но може да се наложи престой, за да се възстанови от непредвидени обстоятелства.

Стъпка 2:  Архивиране на всички бази данни във файл

Командата по-долу създава резервно копие на един файл на всички бази данни с име all-databases-backup.sqld и може да бъде изтрита, след като преобразуването е успешно и няма видими проблеми.
mysqldump --all-databases > all-databases-backup.sql

Стъпка 3:  Записване на съществуващи машини за таблици във файл

Изпълнете следния скрипт, за да запишете съществуващите машини за таблици във файл с име table-engine-backup.sql . След това можете да „импортирате“ или „изпълните“ този файл по-късно, за да конвертирате обратно към оригиналните им двигатели, ако е необходимо.

mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=",Engine,";") FROM information_schema.tables WHERE table_schema NOT IN("mysql","information_schema","performance_schema");' | tee table-engine-backup.sql

Ако трябва да върнете обратно машините за таблици по някаква причина, изпълнете:
mysql < table-engine-backup.sql

Стъпка 4а:  Конвертиране на MyISAM таблици в InnoDB

Командата по-долу ще продължи дори ако дадена таблица не успее и ви позволява да знаете кои таблици не са успели да се преобразуват. Резултатът се записва във файла с име convert-to-innodb.log за по-късен прегледс.
mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=InnoDB;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "MyISAM";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-innodb.log

Стъпка 4b:Преобразувайте всички InnoDB таблици в MyISAM

Тази команда ще продължи дори ако дадена таблица не успее и ви позволява да знаете кои таблици не са успели да се преобразуват. Резултатът също се записва във файла с име convert-to-myisam.log за по-късен преглед.

mysql -Bse 'SELECT CONCAT("ALTER TABLE ",table_schema,".",table_name," ENGINE=MyISAM;") FROM information_schema.tables WHERE table_schema NOT IN ("mysql","information_schema","performance_schema") AND Engine = "InnoDB";' | while read -r i; do echo $i; mysql -e "$i"; done | tee convert-to-myisam.log

Преобразуване на една таблица между MyISAM и InnoDB

Следните команди илюстрират как се извършва преобразуването на една таблица.

Забележка Заменете базата_име с правилното име на базата данни и table_name с правилното име на таблица. Уверете се, че имате валидно резервно копие на въпросната таблица, преди да продължите.

Архивиране на една таблица във файл
mysqldump database_name table_name > backup-table_name.sql

Конвертиране на една таблица в InnoDB

mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=InnoDB;’

Преобразуване на една таблица в MyISAM:

mysql -Bse ‘ALTER TABLE database_name.table_name ENGINE=MyISAM;’

Разгледайте другите ни статии от тази поредица, Ефективност на MySQL:Идентифициране на дълги заявки, за да определите бавните заявки във вашата база данни. Очаквайте следващата ни статия, в която ще разгледаме кеширането и оптимизацията.

Навигация по серии<<Предишна статияСледваща статия>>

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL заявка за създаване на таблица в MySQL

  2. MySQL извлича променлива от Съхранена процедура в PHP PDO

  3. Намерете записи от една таблица, които не съществуват в друга

  4. Как да съхранявате IPv6-съвместим адрес в релационна база данни

  5. Подзаявки с EXISTS срещу IN - MySQL