Медленный запрос на одну БД, но быстрый на его копию - PullRequest
0 голосов
/ 06 июня 2018

У нас есть приложение Laravel (версия 5.4.18), которое подключено к базе данных MySQL (5.6.38) (всего 300 тыс. Строк), тип MyISAM.И у нас есть API-ответ, подобный Model::with('anothermodel')->paginate(25), и в какой-то момент время выполнения этого запроса достигло 18 секунд, что является очень большим значением.Я создал песочницу с копией среды live laravel, которая использует копию той же самой базы данных (на том же сервере), и теперь этот API-ответ выполняется за 2,5 секунды.Если мы пытаемся подключить песочницу Laravel к работающей БД, то выполнение API снова 18 с.Пожалуйста, проверьте изображение.

api demo

Итак, если мы предположим, что проблема в таблице БД живого веб-сайта, но если мы попытаемся измерить этот запросс microtime, тогда это покажет, что время, необходимое для генерации этого запроса и получения данных из базы данных, составляет всего 0,7 сек.

Так что, если мы предположим, что проблема в маршрутах API или в коде Laravel, ноточно такой же код выполняется без проблем, если я просто скопирую его в подкаталог (как песочницу).

Есть идеи?

Также немного информации о сервере: PHP 7.0.29 на сервере Linux сОперативная память 32 ГБ.

Ответы [ 6 ]

0 голосов
/ 16 июня 2018

Вот мой личный опыт работы с очень большой базой данных, с данными более 8 миллионов записей.Я не уверен, насколько это полезно, но вот оно.

Для очень больших записей запрос, который вы пытаетесь выполнить, сильно влияет на время ответа.Например, скажем, если вы пытаетесь найти продукт с именем "abc" и хотите его пининировать.Для этого будут выполнены два запроса.

  1. Первый запрос будет считать все записи, начиная с имени abc, вне вашей базы данных.- Допустим, это заняло 10 секунд, так как громкость высока, и она пойдет сверху вниз.
  2. Второй запрос выполняется, чтобы получить первые 10 или 20 записей, которые вы хотите.Это сильно влияет на время.

    а.Допустим, если у вас много записей с именем "abc", поэтому запрос будет возвращать первые 10 записей гораздо реже, скажем, через 2 секунды.

    б.Но если у вас очень мало записей с именем «abc», тогда запрос будет проходить до базы данных, и это займет еще 10 секунд, поэтому общее время выполнения теперь составляет 20 секунд, тогда как в первом случае это было всего 12с.

Если вы хотите увидеть, где на самом деле уходит время, вы можете использовать laravel debugger tool. Это фактически показывает, какие запросы выполняются, а какой - сколько времени.

Существует несколько других факторов, таких как настройка сервера и задержка.Те, что вы также можете проверить.

Для запросов мое предложение n будет использовать simplePaginate(), до тех пор, пока вы не хотите отображать общее количество записей.

Надеюсь, это помоглоВы немного.

0 голосов
/ 16 июня 2018

Недостаточно информации, чтобы поставить подробный диагноз.Лично я бы начал проверять занятость памяти и процессора на сервере, когда запрос выполняется медленно, htop - хороший инструмент, если у вас нет доступа к любому другому лицензионному программному обеспечению для мониторинга сервера, просто чтобы убедиться, что не толькомашины равны, но и рабочая нагрузка.Часто такие проблемы зависят от блокировки или конфликта ресурсов, а не от конкретного запроса.В конце концов изолируйте последовательность SQL и получите объяснение на обоих серверах.На этом этапе вы сможете воспроизвести проблему, проснувшись с помощью того же клиента, т.е. SQLYOG, и сможете оценить изменения в объяснении и производительности после перестроения индексов или таблиц.Просто делать это и надеяться, что все будет в порядке, не очень полезно, если цель состоит в том, чтобы решить проблему и подготовить документацию о том, как ее исправить в будущем.Да, обычно снижение производительности из-за индекса, который необходимо перестраивать, происходит снова и снова, когда нет программы тщательного обслуживания БД.

0 голосов
/ 16 июня 2018

Вам нужно починить базу данных.

Почему вы сжимаете и восстанавливаете базу данных

В этом обзоре объясняется, как с помощью команды Сжать и восстанавливать базу данных можно предотвратить и исправить следующие проблемы, которые иногда влияют на базу данных:файлы увеличиваются с использованием и файлы становятся поврежденными.

Файлы базы данных растут с использованием По мере добавления и обновления данных и изменения их структуры файл базы данных становится больше.Часть этого роста происходит из новых данных, но некоторые из других источников:

  • Access создает временные скрытые объекты для выполнения различных задач.Иногда эти временные объекты остаются в вашей базе данных после того, как Access больше не нуждается в них.

    Когда вы удаляете объект базы данных, дисковое пространство, которое занимал объект, не восстанавливается автоматически - файл базы данных все еще использует это дисковое пространство,даже если объект удален.

Поскольку файл базы данных заполняется остатками временных и удаленных объектов, его производительность может ухудшиться.Объекты могут открываться медленнее, запросы могут выполняться дольше, чем обычно, а типичные операции обычно кажутся более длинными.

Ссылка:

https://support.office.com/en-us/article/Compact-and-repair-a-database-6ee60f16-aed0-40ac-bf22-85fa9f4005b2

0 голосов
/ 13 июня 2018

У меня есть 3 решения для вас:

1) проверить, оптимизировать и восстановить таблицу с помощью этой команды:

mysqlcheck -u root -p --auto-repair --check --optimize --all-databases

2) если проблема не решена, проверьте план выполнения запроса, используяМониторинг приложений, таких как Newrelic

3) Иногда речь идет не о конкретной таблице, а о повреждении базы данных, попробуйте удалить и создать новую со старыми данными. Как восстановить / воссоздать базу данных mysql по умолчанию для mysql

0 голосов
/ 12 июня 2018

Может быть несколько проблем, одна из них - перестройка индексов, которые адресованы и перед этим делаются резервные копии,

Другая - это сервер, который вы используете, я имею в виду Apache или NGINX.

Посмотрите, что работает для Apache

ps auxf

Мониторинг Apache путем включения состояния сервера

apachectl fullstatus

Хорошее чтение здесь о производительности Apache

0 голосов
/ 09 июня 2018

Вы пытались перестроить индексы на работающей БД?

В MySQL это можно сделать с помощью команды REPAIR <table> QUICK (быстрое восстановление - означает только восстановление индексов - перестроить их).

(Пожалуйста, сделайте резервную копию БД перед применением ... У этой команды почти нет шансов разбить БД, но ...)


Некоторое дополнительное объяснение:

Mysql в основном с самобалансировкойB + деревья для индексов, они стараются быть как можно более плоскими, чтобы обеспечить хорошее время поиска.

Но в некоторых случаях (часто это связано с добавочными вставками данных в столбец DATETIME, например createdAt с индексом)MySQL B + дерево реализации не в состоянии справиться с таким типом нагрузки.Генерируемое дерево обеспечивает производительность, которая постоянно снижается с течением времени (дни, недели).Такие индексы нужно перестраивать ...

Если этот подход вам поможет - перестраивайте индексы один раз за x дней (Один раз в неделю у меня работал в последний раз)

...