Wordpress管理员用户

时间:2013-12-09 15:29:11

标签: php mysql wordpress

我试图为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

2 个答案:

答案 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上的复合索引,只按姓氏排序。