Я довольно новичок в MySQL и работал над следующим запросом, чтобы вывести список значений из таблиц wordpress users/usermeta. Запрос работает отдельно от производительности, это ужасно, и я не уверен, как его улучшить.Оптимизация/запрос MySQL
Задание длится 12+ секунд, и только с 400 пользователями это станет огромной проблемой, если будет добавлено больше.
Я заметил, что MySQL сообщает, что нет уникальных столбцов, но я не уверен, как это исправить, поскольку идентификатор пользователя уже является частью результатов.
Это запрос по умолчанию, полный запрос добавляет дополнительные вычисления с использованием значений lat/long для определения расстояния для поиска в почтовом индексе, однако это, похоже, не добавляет много дополнительного времени.
Основная часть, с которой я боролся, заключается в том, что значения сохраняются как meta_key и meta_value с ассоциированным user_id как внешним ключом.
SELECT DISTINCT
wp_users.ID,
wp_users.user_email,
city_latitude.meta_value as cityLat,
city_longitude.meta_value as cityLong,
service_name.meta_value as service_name,
service_address.meta_value as service_address,
service_category.meta_value as service_category,
service_level.meta_value as service_level,
service_info.meta_value as service_info,
service_area.meta_value as service_area,
service_active.meta_value as service_active,
service_keyword.meta_value as service_keyword
FROM
wp_usermeta AS city_latitude
LEFT JOIN wp_usermeta as city_longitude ON city_latitude.user_id = city_longitude.user_id
LEFT JOIN wp_usermeta as service_name ON service_name.user_id = city_longitude.user_id
LEFT JOIN wp_usermeta as service_category ON service_category.user_id = city_longitude.user_id
LEFT JOIN wp_usermeta as service_address ON service_address.user_id = city_longitude.user_id
LEFT JOIN wp_usermeta as service_level ON service_level.user_id = city_longitude.user_id
LEFT JOIN wp_usermeta as service_info ON service_info.user_id = city_longitude.user_id
LEFT JOIN wp_usermeta as service_area ON service_area.user_id = city_longitude.user_id
LEFT JOIN wp_usermeta as service_active ON service_active.user_id = city_longitude.user_id
LEFT JOIN wp_usermeta as service_keyword ON service_keyword.user_id = city_longitude.user_id
INNER JOIN wp_users ON wp_users.ID = city_latitude.user_id
WHERE city_latitude.meta_key = 'service_lat'
AND city_longitude.meta_key = 'service_long'
AND (service_name.meta_key = 'service_name' AND service_name.meta_value != 'Anonymous')
AND (service_category.meta_key = 'service_category' ".$query_category.")
AND service_address.meta_key = 'service_address'
AND (service_level.meta_key = 'wp_user_level' AND service_level.meta_value = 0)
AND service_info.meta_key = 'service_additional'
AND service_area.meta_key = 'service_area'
AND service_keyword.meta_key = 'service_keywords'
AND (service_active.meta_key = 'active' AND service_active.meta_value = 1)
ORDER BY service_name ASC
Я обновил запрос с некоторыми из приведенных ниже предложений, которые уже имеют большое значение. Я все еще думаю, что сам запрос можно улучшить, уменьшив количество объединений и т. Д., Если у кого-то есть больше идей, которые я бы хотел их услышать.
Это запрос, который включает изменения и дополнительную часть для поиска по расстоянию.
SELECT DISTINCT
wp_users.ID,
wp_users.user_email,
city_latitude.meta_value as cityLat,
city_longitude.meta_value as cityLong,
service_name.meta_value as service_name,
service_address.meta_value as service_address,
service_category.meta_value as service_category,
service_level.meta_value as service_level,
service_info.meta_value as service_info,
service_area.meta_value as service_area,
service_active.meta_value as service_active,
service_keyword.meta_value as service_keyword,
((ACOS(SIN($userLat * PI()/180) * SIN(city_latitude.meta_value * PI()/180) + COS($userLat * PI()/180) * COS(city_latitude.meta_value * PI()/180) * COS(($userLng - city_longitude.meta_value) * PI()/180)) * 180/PI()) * 60 * 1.1515) AS distance
FROM
wp_usermeta AS usermeta
LEFT JOIN wp_usermeta as city_longitude ON city_longitude.user_id = usermeta.user_id AND city_longitude.meta_key = 'service_long'
LEFT JOIN wp_usermeta as city_latitude ON city_latitude.user_id = usermeta.user_id AND city_latitude.meta_key = 'service_lat'
LEFT JOIN wp_usermeta as service_name ON service_name.user_id = usermeta.user_id AND service_name.meta_key = 'service_name'
LEFT JOIN wp_usermeta as service_category ON service_category.user_id = usermeta.user_id AND service_category.meta_key = 'service_category'
LEFT JOIN wp_usermeta as service_address ON service_address.user_id = usermeta.user_id AND service_address.meta_key = 'service_address'
LEFT JOIN wp_usermeta as service_level ON service_level.user_id = usermeta.user_id AND service_level.meta_key = 'wp_user_level'
LEFT JOIN wp_usermeta as service_info ON service_info.user_id = usermeta.user_id AND service_info.meta_key = 'service_additional'
LEFT JOIN wp_usermeta as service_area ON service_area.user_id = usermeta.user_id AND service_area.meta_key = 'service_area'
LEFT JOIN wp_usermeta as service_active ON service_active.user_id = usermeta.user_id AND service_active.meta_key = 'active'
LEFT JOIN wp_usermeta as service_keyword ON service_keyword.user_id = usermeta.user_id AND service_keyword.meta_key = 'service_keywords'
INNER JOIN wp_users ON wp_users.ID = usermeta.user_id
WHERE (service_name.meta_value != '' AND service_name.meta_value != 'Anonymous') AND service_level.meta_value = 0 AND service_active.meta_value = 1
HAVING distance < $search_distance
ORDER BY distance ASC
Что EXPLAIN дает? Пожалуйста, покажите нам это. Есть ли какие-либо объединения, требующие полного сканирования таблицы? И вам нужно добавить условия WHERE к соответствующим компонентам ON! – Seb
@P Heron - можете ли вы опубликовать созданные из таблицы данные с определенной датой выборки. Нет необходимости вступать в wp_usermeta более одного раза. Я отправлю вам запрос, если вы отправите некоторые данные в http: // sqlfiddle.com/ –
@ Бернд Буффен - Это было бы здорово. Я установил некоторые данные в [link] (http://sqlfiddle.com/#!9/af672a). Я никогда не использовал это до того, как так модно его ок –