Мое приложение зависит от запуска "Показать столбцы" для определенных таблиц. Выполнение занимает около 60 мс, в то время как все остальные наши запросы занимают менее 1 мс. Запросы information_schema
напрямую еще медленнее.
База данных содержит около 250 баз данных, от 100 до 200 таблиц на базу данных (всего около 20 тыс. Таблиц).
- Как я могу узнать, почему эти операции такие медленные?
- Возможно, есть какие-то настройки, которые я могу изменить, чтобы они работали быстрее или для кэширования на стороне SQL?
(Приложение выполняет около 14 таких запросов на загрузку страницы - я хорошо знаю, что этот устаревший код необходимо очистить, но я ищу возможные варианты, пока я работаю над долгосрочным исправлением.)
Ответы:
MySQL пересчитывает статистику таблиц для определенных операций, которые обращаются к
INFORMATION_SCHEMA
таблицам (SHOW COLUMNS
это просто удобный псевдоним для запросовINFORMATION_SCHEMA.COLUMNS
). Задайте для свойства innodb_stats_on_metadata значение false, что предотвратит повторный расчет при запросе метаданных из таблицы.и добавьте следующее к
my.cnf
источник
[mysqld]
там. Для многих может быть очевидным, что этот параметр подходит для mysqld, но может не быть очевидным для тех, кто задает этот вопрос. Кстати, это ускорилоSELECT COUNT(*)
на одном из моихinformation_schema
столов до 6 секунд за минуту. Все еще медленно, но огромное улучшение.Я предлагаю вам создать базу данных, в которой есть
INFORMATION_SCHEMA
таблицы (или только те, которые вам нужны) в качестве копий. Индексируйте их соответствующим образом, и вы получите прирост производительности.Проблема синхронизации между этой базой данных и
INFORMATION_SCHEMA
хитрая, хотя.У вас может быть процедура, которая синхронизирует эти таблицы каждый час или каждые 5 минут (как часто меняется структура таблиц?).
Другая идея заключается в том, чтобы использовать MySQL Proxy для перехвата любых
ALTER TABLE
операторов (и,CREATE
и,DROP
и,CREATE INDEX
и так далее, для любых других операторов, которые изменяют необходимую информацию), а затем синхронизировать реплицированную информационную схему после успешного выполнения этих операторов.Если вам нужны только имена столбцов, а не какая-либо другая информация, такая как тип данных, длина или доступные индексы, вы, возможно, могли бы заменить использование
SHOW COLUMNS
с (быстрыми) запросами, которые возвращают только 1 строку,LIMIT 1
вообще или без них, либо либо,LIMIT 0
либо:Несмотря на общий совет против использования
SELECT *
, это может быть законным случаем, где ничто другое не полезно. (все остальное, кроме*
, может привести к ошибке!)источник
В данном конкретном случае, я думаю,
INFORMATION_SCHEMA
это красная сельдь. Судя по моим собственным тестамSHOW COLUMNS
производительности,innodb_stats_on_metadata
переменная, похоже, не имеет никакого значения для таблиц MyISAM или InnoDB.Тем не менее, из руководства MySQL 5.0 ...
Похоже, что это было удалено из руководства, начиная с MySQL 5.5, но все еще применимо в этой версии ...
Информация о поле, возвращаемая с набором результатов запроса, содержит ту же информацию, что и возвращаемая
SHOW COLUMNS
, поэтому aSELECT * FROM my_table LIMIT 0
должно достигать того же самого, не создавая временную таблицу на диске для каждого запроса.Быстрый пример, чтобы просто получить имена полей в PHP ...
Получение информации о поле таким способом немного более неудобно для декодирования. Вам придется обратиться к описанию базовой
MYSQL_FIELD
структуры, чтобы извлечь типы данных и флаги, но в моей системе она работает примерно в 7 раз быстрее.источник
Мне нравится первое предложение в ответе @ yerpcube (+1), но я хотел бы предложить кое-что
--no-data
--routines
--triggers
--all-databases
или--databases
затем список баз данных, которые вы хотитеТаким образом, ваш mysqldump должен выглядеть следующим образом:
Вот и все. В дальнейшем все, что вам нужно сделать, это подключиться к этому экземпляру базы данных порта 3307 и выполнить любой запрос, связанный со схемой, к вашему сердцу. Если вам известна какая-либо таблица в производственной базе данных, которая изменяется, просто mysqldump схема из производства и снова загрузите ее в экземпляр порта 3307.
ВНИМАНИЕ: Если вы устанавливаете экземпляр mysql на той же машине, что и производственная, убедитесь, что вы подключаетесь к этому экземпляру, используя
Если вы выполните
Это будет производство шлангов. Так что будь осторожен !!!!
Альтернативой было бы просто использовать отдельный сервер БД.
источник