我试图为wordpress编写一个sql查询,但为什么我的查询速度很慢?需要3.5秒。我试图复制wordpress wordpress/wp-admin/users.php
下的那个,它选择用户但速度快。
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 :(得分: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
答案 1 :(得分:0)
使用给定的查询应该相当快,因为您在wp_users表上对索引进行排序,MySQL能够找到您想要提取的特定30条记录。
MySQL只需从wp_users中提取30条记录,然后为每条记录进行两次查找(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
但是,当使用lastname,firstname进行排序时,MySQL必须在wp_users表中提取所有8,500条记录,对连接进行所有查找(8,500 * 2 = 17,000次查找),每个查找都必须进行表扫描,然后对它们进行排序在临时表中,它可以找到你想要的30条记录。
这里的解决方案可能是创建与第一部分中提到的相同的覆盖索引。你想在wp_usermeta表上进行自联接,并希望MySQL在连接回wp_users表之前实际使用它的index merge optimization来找到你想要的30条记录:
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上的复合索引,只按姓氏排序。