I have a search function I built on a Wordpress site for searching names and localities that is like so:
#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
This takes about 3 seconds to run. I am trying to see if there is a faster way I can write this query. I have innoDB and indexing but there are a lot of records. This is the fastest version of the query I have but 3 seconds is still pretty slow. Any ideas?
EDIT (SQL explain results, the second to last value is the number of rows):
'1', 'PRIMARY', 'wp_usermeta', 'ref', 'meta_key,FH_DanB_1', 'FH_DanB_1', '768', 'const', '98252', 'Using where'
'2', 'DEPENDENT SUBQUERY', 'wp_posts', 'index_subquery', 'type_status_date,post_author', 'post_author', '8', 'func', '1', 'Using where'
'3', 'DEPENDENT SUBQUERY', 'wp_posts', 'index_subquery', 'type_status_date,post_author', 'post_author', '8', 'func', '1', 'Using where'
'4', 'UNION', 'wp_usermeta', 'index', 'meta_key,FH_DanB_1', 'user_id', '8', NULL, '510714', 'Using where'
'6', 'DEPENDENT SUBQUERY', 'wp_posts', 'index_subquery', 'type_status_date,post_author', 'post_author', '8', 'func', '1', 'Using where'
'7', 'DEPENDENT SUBQUERY', 'wp_posts', 'index_subquery', 'type_status_date,post_author', 'post_author', '8', 'func', '1', 'Using where'
'5', 'DEPENDENT SUBQUERY', 'wp_usermeta', 'ref', 'user_id,meta_key,FH_DanB_1', 'FH_DanB_1', '776', 'const,func', '1', 'Using where'
wp_usermeta has over 500k rows, but I think I should index the column meta_value?
Not sure if I can make the query itself syntactically faster.
Two tables used here are 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, popularity, robotsmeta, meta_robots) and wp_usermeta (meta_id, user_id, meta_key, meta_value). The wp_posts.post_author value is the same as wp_usermeta.user_id. Wp_posts has over 100K rows, wp_usermeta has over 500k.
EXPLAIN
of the query. – G-Nugget