Я создаю сайт, который использует много запросов к базе данных, поэтому я немного боялся, что это может произойти.
Итак, проблема в том, что у меня есть несколько запросов, которые используют много JOIN
s и некоторые из таблиц имеют пару тысяч записей, в то время как некоторые другие имеют около 200-300 тысяч записей.У меня был опыт замедления работы сайта, и мне приходилось оптимизировать некоторые запросы.
Дело в том, что в этом случае на моем локальном компьютере конкретный раздел, использующий эти запросы, занимает около 2,5 секунд для загрузки с включенным регулированием сети какОбычный Wi-Fi.При хорошем Wi-Fi загрузка занимает около 1,3 секунды.
На моем производственном сервере, который является виртуальной машиной в DigitalOcean, требуется примерно 5 минут! для загрузки точно такого же контента с точно таким же запросом.Теперь я не эксперт, но мой компьютер не работает в 120 раз быстрее, чем производственный сервер DigitalOcean.
Мой ноутбук имеет следующие характеристики: Intel Core i7-6700 HQ, 16 ГБ оперативной памяти DDR4 и серверработающий на жестком диске со скоростью 5400 об / мин, его нет даже на моем SSD-накопителе, а только там, где используется движок MySQL.
Рабочий сервер изначально был базовым экземпляром DO с 1 ГБ ОЗУ и 1 VCPU.Я подумал, что это, вероятно, нуждается в некотором повышении, поэтому я временно обновил его, чтобы иметь 2VCPU и 2 ГБ оперативной памяти, но это не имело никакого значения.Другие разделы загружаются невероятно быстро, за исключением одного, который использует много объединений.
Теперь я не эксперт, но мой компьютер не в 120 раз быстрее сервера, и он также работает кучадругие процессы.У меня есть GeForce 1070M, но я не думаю, что это влияет на производительность mysql.
Я попытался разделить запрос на как можно меньше JOIN
s, а затем выполнить несколько простых запросов, чтобы добавить дополнительныеинформация в мой информационный массив, но потом у меня возникла другая проблема.С такой логикой даже на моем компьютере он завис на 4-5 секунд, а затем неожиданно загрузил контент.
Ниже приведены скриншоты вкладки сети Chrome, показывающие разницу во времени.Как видите, все остальное загружается невероятно быстро, за исключением начальной загрузки.Я почти уверен, что это проблема MySQL, но разница ошеломляет.Я подумываю о попытке загрузить сайт на 16 ГБ экземпляра памяти с 6VCPU на DigitalOcean, чтобы увидеть, связано ли это с памятью / процессором, но я не уверен, что мой клиент хотел бы платить 80 долларов США в месяц или больше за такую виртуальную машину.
Одним из возможных решений, о котором я думал, было разделение таблиц Localidades
и Asentamientos
(в каждой из них около 200-300 тыс. Записей) на 32 таблицы меньшего размера, по одной для каждого штата Мексики, и имеющиеспециальная функция для каждого состояния для ссылки на другую таблицу, но я не думаю, что это будет ни масштабируемой, ни хорошей практикой.
Я также добавил расчетную стоимость запроса ниже.
Myлокальный компьютер имеет:
- Windows 10 1803
- Apache / 2.4.25 (Win64)
- MySQL 5.7.23
Myрабочий сервер имеет:
- Ubuntu 18.04.1 LTS
- Apache / 2.4.29 (Ubuntu)
- 5.7.24-0ubuntu0.18.04.1
Есть идеи, что я могу сделать, чтобы решить эту проблему?
Сгенерированный запрос выглядит следующим образом:
SELECT
`Propiedades`.*,
`Propiedades`.`directorio` AS `main_dir`,
DATEDIFF(Propiedades.fecha_finalizacion,
'2018-12-02 11:11:49') AS quedan,
`OperacionesPorPropiedad`.*,
`Operaciones`.`nombre_operacion`,
`Operaciones`.`nombre_operacion_slug`,
`TiposDePropiedades`.*,
`FotografiasPorPropiedad`.*,
`Empresas`.`nombre_empresa`,
`Estados`.*,
`Municipios`.*,
`Localidades`.*,
`Asentamientos`.*,
`Clientes`.`nombres`,
`Clientes`.`apellidos`,
`Clientes`.`email`,
`TiposDeClientes`.*
FROM
`Propiedades`
JOIN
`OperacionesPorPropiedad` ON `OperacionesPorPropiedad`.`id_propiedad` = `Propiedades`.`id_propiedad`
JOIN
`Operaciones` ON (`Operaciones`.`id_operacion` = `OperacionesPorPropiedad`.`id_operacion`
AND `OperacionesPorPropiedad`.`id_propiedad` = Propiedades.id_propiedad)
JOIN
`TiposDePropiedades` ON `TiposDePropiedades`.`id_tipo` = `Propiedades`.`id_tipo`
JOIN
`FotografiasPorPropiedad` ON (`FotografiasPorPropiedad`.`id_propiedad` = `Propiedades`.`id_propiedad`
AND `FotografiasPorPropiedad`.`orden` = 1)
JOIN
`Empresas` ON `Empresas`.`id_empresa` = `Propiedades`.`id_empresa`
JOIN
`Estados` ON `Estados`.`id_estado` = `Propiedades`.`id_estado`
LEFT OUTER JOIN
`Municipios` ON `Municipios`.`id_municipio` = `Propiedades`.`id_municipio`
LEFT OUTER JOIN
`Localidades` ON `Localidades`.`id_localidad` = `Propiedades`.`id_localidad`
LEFT OUTER JOIN
`Asentamientos` ON `Asentamientos`.`id_asentamiento` = `Propiedades`.`id_asentamiento`
JOIN
`Clientes` ON `Clientes`.`id_cliente` = `Empresas`.`id_cliente`
JOIN
`TiposDeClientes` ON (`Clientes`.`id_tipo_cliente` = `TiposDeClientes`.`id_tipo_cliente`
AND `Clientes`.`id_cliente` = `Empresas`.`id_cliente`)
WHERE
`Propiedades`.`id_estatus_propiedad` = 1
GROUP BY `Propiedades`.`id_propiedad`
ORDER BY FIELD(`Propiedades`.`destacada`, '1', '0') , FIELD(`Clientes`.`id_tipo_cliente`, 1, 2, 3) , RAND()
LIMIT 24