如何加速这个Wordpress Mysql查询?

时间:2012-12-13 20:27:06

标签: mysql performance wordpress

我有一个我在Wordpress网站上构建的搜索功能,用于搜索名称和地点,如下所示:

#name search
select user_id from wp_usermeta where meta_key='first_name' 
AND meta_value LIKE 'term' 
AND user_id in (SELECT post_author FROM wp_posts WHERE post_type='attachment' 
AND length(post_content) > 0 
AND length(post_title) > 0 
AND post_author in (SELECT post_author FROM wp_posts WHERE post_type='article')) 

UNION 

#locality search
select user_id from wp_usermeta where meta_key in ('zip', 'city', 'state', 'country') 
AND user_id in (select user_id from wp_usermeta where meta_key = 'user_type'and meta_value = 'user') 
AND (meta_value LIKE 'term') 
AND user_id in (SELECT post_author FROM wp_posts WHERE post_type='attachment' 
AND length(post_content) > 0 
AND length(post_title) > 0 
AND post_author in (SELECT post_author FROM wp_posts WHERE post_type='article')) 
group by user_id

这需要大约3秒钟才能运行。我试图看看是否有更快的方式来编写此查询。我有innoDB和索引,但有很多记录。这是我查询的最快版本,但3秒仍然很慢。有什么想法吗?

EDIT(SQL解释结果,倒数第二个值是行数):

' 1',' PRIMARY',' wp_usermeta',' ref',' meta_key,FH_DanB_1', ' FH_DanB_1',' 768',' const',' 98252','使用where'

' 2','依赖子信息' wp_posts',' index_subquery',' type_status_date,post_author' ,' post_author',' 8',' func',' 1','使用where'

' 3','依赖子信息' wp_posts',' index_subquery',' type_status_date,post_author' ,' post_author',' 8',' func',' 1','使用where'

' 4',' UNION',' wp_usermeta',' index',' meta_key,FH_DanB_1', ' user_id',' 8',NULL,' 510714','使用where'

' 6','相关提示',' wp_posts',' index_subquery',' type_status_date,post_author' ,' post_author',' 8',' func',' 1','使用where'

' 7','依赖子信息' wp_posts',' index_subquery',' type_status_date,post_author' ,' post_author',' 8',' func',' 1','使用where'

' 5','相关提示',' wp_usermeta',' ref',' user_id,meta_key,FH_DanB_1&# 39;,' FH_DanB_1',' 776',' const,func',' 1','使用where'

wp_usermeta有超过500k行,但我想我应该将列meta_value编入索引?

不确定我是否可以在语法上更快地进行查询。

这里使用的两个表是wp_posts(post_author,post_date,post_date_gmt,post_content,post_title,post_excerpt,post_status,comment_status,ping_status,post_password,post_name,to_ping,pinged,post_modified,post_modified_gmt,post_content_filtered,post_parent,guid,menu_order,post_type, post_mime_type,comment_count,up,down,popular,robotsmeta,meta_robots)和wp_usermeta(meta_id,user_id,meta_key,meta_value)。 wp_posts.post_author值与wp_usermeta.user_id相同。 Wp_posts有超过100K行,wp_usermeta超过500k。

1 个答案:

答案 0 :(得分:0)

我无法测试您的查询,但我会这样做:

  • 用内部联接替换IN子句
  • meta_value LIKE 'term'替换为meta_value='term'
  • 删除GROUP BY因为联合查询(没有union all子句)已经删除了重复项
  • 在键上添加索引,也可能在某些文本字段上添加索引。

如果我没有犯错,这应该是结果查询:

select wp_usermeta.user_id
from
  wp_usermeta inner join wp_posts wp1
  on wp_usermeta.user_id=wp1.post_author and wp1.post_type='attachment'
  inner join wp_posts wp2
  on wp_usermeta.user_id=wp2.post_author and post_type='article'
where
  wp_usermeta.meta_key='first_name' 
  AND wp_usermeta.meta_value='term' 
  AND length(wp_usermeta.post_content) > 0 
  AND length(wp_usermeta.post_title) > 0 

UNION 

select wp_um1.user_id
from
  wp_usermeta wp_um1 inner join wp_usermeta wp_um2
  on wp_um1.user_id=wp_um2.user_id and wp_um2.meta_key = 'user_type'
     and wp_um2.meta_value = 'user'
  inner join wp_posts wp1
  on wp_usermeta.user_id=wp1.post_author and wp1.post_type='attachment'
  inner join wp_posts wp2
  on wp_usermeta.user_id=wp2.post_author and post_type='article'
where
  wp_um1.meta_key in ('zip', 'city', 'state', 'country')
  AND (wp_um1.meta_value = 'term')
  AND length(wp_um1.post_content) > 0
  AND length(wp_um1.post_title) > 0

编辑:我想尝试的最后一个想法就是这个。你可以替换这部分:

 inner join wp_posts wp1
  on wp_usermeta.user_id=wp1.post_author and wp1.post_type='attachment'
  inner join wp_posts wp2
  on wp_usermeta.user_id=wp2.post_author and post_type='article'

这个:

inner join (select post_author
            from wp_posts
            where post_type in ('attachment','article')
            group by post_author
            having count(*)>1) wp on wp_usermeta.user_id = wp.post_author

取决于您的数据结构如何,它可以使查询更快,但也更慢......