2013-12-09 3 views
-1

Я пытался написать sql-запрос для wordpress, но почему мой запрос очень медленный? он занимает 3,5 секунды. im пытается скопировать файл под Wordpress wordpress/wp-admin/users.php, который выбирает пользователей, но быстро.Wordpress Admin Users

SELECT 
    usr.display_name, 
    m1.meta_value, 
    m2.meta_value 
from wp_users usr 
JOIN wp_usermeta m1 ON (m1.user_id = usr.id AND m1.meta_key = 'first_name') 
JOIN wp_usermeta m2 ON (m2.user_id = usr.id AND m2.meta_key = 'last_name') 
ORder by usr.user_login 
LIMIT 0,30 
+0

Это ваш запрос, который вы копировали с user.php? – sulmanpucit

+0

Я сделал запрос, чтобы скопировать, как работает Wordpress-запрос для пользователей – Cindy93

+0

Сколько записей делает это? Вы показываете имя и фамилию? –

ответ

0

Используя запрос, как указано должно быть достаточно быстро, так как Вы заказываете на индекс по Таблица wp_users, MySQL может найти 30 записей, которые вы хотите вытащить.

MySQL должен только вытащить 30 записей из wp_users, затем выполнить два поиска на запись для соединения (30 * 2 = 60). К сожалению, для каждого из этих запросов требуется сканирование таблицы, поскольку индекс на wp_usermeta.user_id позволяет получить только половину пути к конкретной записи, которую они пытаются найти. Тем не менее, поскольку это всего 30 записей (60 запросов), это должно быть довольно быстро. Одним из способов улучшить это было бы добавление составного индекса на wp_usermeta.user_id + wp_usermeta.meta_key, что позволило бы избежать сканирования мелкой таблицы.

Возможно, у вас есть еще лучший успех с индексом покрытия, если значения достаточно малы, чтобы соответствовать индексу «префикс», создав составной индекс для всех трех полей: wp_usermeta.user_id + wp_usermeta.meta_kety + wp_usermeta. meta_value.

Однако при заказе по фамилии, имени, MySQL необходимо вытащить все 8500 записей в вашей таблице wp_users, выполнить все поиски для соединения (8 500 * 2 = 17 000 запросов), каждый из которых должен выполнить сканирование таблицы, а затем заказать их во временную таблицу, прежде чем она сможет найти 30 записей, которые вы хотите.

Решение может состоять в том, чтобы создать тот же индекс покрытия, который указан в первой части. Вы хотите сделать автообъединение на столе wp_usermeta и надеемся, что MySQL фактически использует index merge optimization, чтобы найти 30 записей, которые вы хотите, прежде чем делать объединение назад к wp_users таблице:

SELECT 
    usr.display_name, 
    m1.meta_value, 
    m2.meta_value 
FROM wp_usermeta m1 
JOIN wp_usermeta m2 
    ON (m1.user_id = m2.user_id AND m1.meta_key = 'lastname' AND m2.meta_key = 'firstname' 
JOIN wp_users usr 
    ON m1.user_id = usr.id 
ORDER BY m1.meta_value, m2.meta_value 
LIMIT 0,30 

Если это Безразлично для вас это не сработает, а затем закажите только по фамилии, используя составной индекс на странице wp_usermeta.meta_key + wp_usermeta.meta_value.

0

FWIW,

Я думаю, что это более простой запрос ...

SELECT u.display_name 
    , MAX(CASE WHEN m.meta_key = 'first_name' THEN m.meta_value END) first_name 
    , MAX(CASE WHEN m.meta_key = 'last_name' THEN m.meta_value END) last_name 
    FROM wp_users u 
    JOIN wp_usermeta m 
    ON m.user_id = u.id 
GROUP 
    BY u.id 
ORDER 
    BY u.user_login 
LIMIT 0,30 
+0

nope .. ваш запрос все еще очень медленный, и потребовалось 11 секунд – Cindy93

+0

У вас есть индекс UNIQUE (или PK) на (id, meta_key)? – Strawberry

+0

его 'user_id' – Cindy93