Сейчас почти в каждой статье упоминается, что надо использовать только utf, потому что это современно, универсально и вообще очень полезно. Ни в коей мере не отрицая этот факт, хотелось бы высказать недоумение тем авторам, которые одновременно с этим говорят скорости работы скриптов, аппелируя к тому, что лучше писать ++i чем i++, по причине скорости работы.
Итак сюрприз — работа с utf медленнее чем с cp1251. Потому что больше размер и нет «выравнивания» букв по байтам. Речь идет о php/mysql
На самом в этом ничего особо страшного нет. В отличии от косяков в коде, использование utf не так сильно замедляет работу, а кроме того, замедляет линейно, так что вопрос в большинстве случаев очень просто решается масштабированием. Если Вы никогда не пытались выбить из заказчика/работодателя денег на сервер помощнее, это Вас должно успокоить.
Если же не успокоило, то ниже несколько цифр, которые возможно будут Вам полезны.
Пациент: не сильно мощный вдс, один единственный на ноде (так его проще таскать туда сюда, но здесь это не важно), пара таблиц на несколько миллионов строк, русский текст, немного английского. Перед каждым тестом ребут, сервер ничем больше не нагружен. Тесты проводятся минимум 3 раза, в таблицу идет среднее.
*1: Пребывая в шоке от этих цифр, был запущен аналогичный тест на локалхосте, преимущество сократилось до 3.02 раза. Возможно что-то куда-то не попадало в кэш или излишне вываливалось на диск в случае utf, данных-то больше.
*2: Memory таблицы используются для поиска точных вхождений, в них чисто русский текст и немного пробелов, получается просто и шустро. Примерно 2 миллиона строк. Размер memory таблиц в utf8 в 3 раза больше cp1251, т.к. используется фиксированный размер (для memory по другому никак) и uft8 в нем резервирует 3 байта под символ.
*3: Для innoDB полнотекстовый индекс не тестировался по причине отсутствия поддержки оных в innoDB. В innoDB использовалась таблица несколько другого размера чем в MyISAM и другой вдс, поэтому прямого сравнения абсолютных результатов нет.
*4: Сильно непонятно почему импорт в innoDB столько занимал. Для MyISAM разница между импортом и экспортом минимальна.
И немного общих слов. Эта «статья» вообще говоря в черновом варианте возникла несколько лет назад. Сейчас сюда добавлен только сфинкс и заново проведены тесты. А возникла она в результате спора на каком-то форуме, по поводу перспективности utf и что мол другие кодировки через год умрут. Но не умерли.
Причем проблемы в php/mysql, например, до сих пор остались самые разные. То надо писать utf, то utf-8, то utf8. И даже utf может быть как ru_RU.UTF так и en_EN.UTF, что дает забавные эффекты с iconv //ignore //translit, уж бог знает почему. Локаль в случае установки php как модуля едина на весь сервер со всеми вытекающими, и даже при правильной локали использовать обычные функции для работы со строками нельзя, надо использовать их аналоги поддерживающие эту работу. В общем utf безусловно передовая технология… но применять ее надо вдумчиво и без излишнего фанатизма.
P.S.: Тем кто любит сжимать траффик прокси-серверами на заметку — хтмл файл в утф8 на 5-20% больше, даже в gzip-е
Итак сюрприз — работа с utf медленнее чем с cp1251. Потому что больше размер и нет «выравнивания» букв по байтам. Речь идет о php/mysql
На самом в этом ничего особо страшного нет. В отличии от косяков в коде, использование utf не так сильно замедляет работу, а кроме того, замедляет линейно, так что вопрос в большинстве случаев очень просто решается масштабированием. Если Вы никогда не пытались выбить из заказчика/работодателя денег на сервер помощнее, это Вас должно успокоить.
Если же не успокоило, то ниже несколько цифр, которые возможно будут Вам полезны.
Пациент: не сильно мощный вдс, один единственный на ноде (так его проще таскать туда сюда, но здесь это не важно), пара таблиц на несколько миллионов строк, русский текст, немного английского. Перед каждым тестом ребут, сервер ничем больше не нагружен. Тесты проводятся минимум 3 раза, в таблицу идет среднее.
Что за данные | Результаты UTF | Результаты CP1251 | Преимущество cp1251 |
---|---|---|---|
MyISAM (text, text, int, int) | ***** | ***** | ***** |
Исходный размер БД | 1.250 Гб | 0.975 Гб | 1.28 раза |
Основные данные | 706 Мб | 479 Мб | 1.47 раза |
Индексные данные | 544 Мб | 496 Мб | 1.09 раза |
Запрос на удаление части строк | 16 сек | 7 сек | 2.28 раза |
Удаление фултекст индекса | 26 сек | 23 сек | 1.13 раза |
Построение фултекст индекса | 6 мин 22 сек | 3 мин 12 сек | 1.98 раза |
Запрос на поиск точного вхождения, 10 раз *1 | 9.67 сек | 1.92 сек | 5.03 раза |
mysqldump экспорт в файл | 8.8 сек | 4.9 сек | 1.79 раза |
mysql импорт из файла | 13.8 сек | 8.7 сек | 1.58 раза |
размер *.sql файла | 773 Мб | 526 Мб | 1.46 раза |
Индексация sphinx-ом | 103 сек | 41 сек | 2.51 раза |
Размер базы sphinx-а | 680 Мб | 433 Мб | 1.57 раза |
innoDB (text, text, int, int) *3 | ***** | ***** | ***** |
Исходный размер БД | 925 Мб | 629 Мб | 1.47 раза |
Запрос на удаление части строк | 21.2 сек | 12 сек | 1.76 раза |
Запрос на поиск точного вхождения, 10 раз | 33.47 сек | 21.89 сек | 1.52 раза |
mysqldump экспорт в файл | 23 сек | 17 сек | 1.35 раза |
mysql импорт из файла *4 | 8м 24сек | 5м 41 сек | 1.47 раза |
размер *.sql файла | 748 Мб | 510 Мб | 1.46 раза |
Memory int, char(128) *2 | ***** | ***** | ***** |
Memory таблицы размер | 515 Мб | 179 Мб | 2.87 раза |
Memory таблицы длина строки | 390 | 133 | 2.93 раза |
Memory таблицы 1000 поисков, что-то найдено каждый раз | 1.9 сек | 0.32 сек | 5.93 раза |
Memory таблицы 1000 поисков, ничего не найдено | 1.8 сек | 0.28 сек | 6.42 раза |
*1: Пребывая в шоке от этих цифр, был запущен аналогичный тест на локалхосте, преимущество сократилось до 3.02 раза. Возможно что-то куда-то не попадало в кэш или излишне вываливалось на диск в случае utf, данных-то больше.
*2: Memory таблицы используются для поиска точных вхождений, в них чисто русский текст и немного пробелов, получается просто и шустро. Примерно 2 миллиона строк. Размер memory таблиц в utf8 в 3 раза больше cp1251, т.к. используется фиксированный размер (для memory по другому никак) и uft8 в нем резервирует 3 байта под символ.
*3: Для innoDB полнотекстовый индекс не тестировался по причине отсутствия поддержки оных в innoDB. В innoDB использовалась таблица несколько другого размера чем в MyISAM и другой вдс, поэтому прямого сравнения абсолютных результатов нет.
*4: Сильно непонятно почему импорт в innoDB столько занимал. Для MyISAM разница между импортом и экспортом минимальна.
И немного общих слов. Эта «статья» вообще говоря в черновом варианте возникла несколько лет назад. Сейчас сюда добавлен только сфинкс и заново проведены тесты. А возникла она в результате спора на каком-то форуме, по поводу перспективности utf и что мол другие кодировки через год умрут. Но не умерли.
Причем проблемы в php/mysql, например, до сих пор остались самые разные. То надо писать utf, то utf-8, то utf8. И даже utf может быть как ru_RU.UTF так и en_EN.UTF, что дает забавные эффекты с iconv //ignore //translit, уж бог знает почему. Локаль в случае установки php как модуля едина на весь сервер со всеми вытекающими, и даже при правильной локали использовать обычные функции для работы со строками нельзя, надо использовать их аналоги поддерживающие эту работу. В общем utf безусловно передовая технология… но применять ее надо вдумчиво и без излишнего фанатизма.
P.S.: Тем кто любит сжимать траффик прокси-серверами на заметку — хтмл файл в утф8 на 5-20% больше, даже в gzip-е