0

次のような名前と地域を検索するために、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 Explain 結果、最後から 2 番目の値は行数):

'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 には 50 万行を超える行がありますが、列 meta_value にインデックスを付ける必要があると思いますか?

クエリ自体を構文的に高速化できるかどうかはわかりません。

ここで使用される 2 つのテーブルは 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) および wp_usermeta (meta_id、user_id、meta_key、meta_value)。wp_posts.post_author 値は wp_usermeta.user_id と同じです。wp_posts には 10 万行以上、wp_usermeta には 50 万行以上あります。

4

1 に答える 1

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

データの構造によっては、クエリが高速になる可能性がありますが、遅くなる可能性もあります...

于 2012-12-13T20:46:01.040 に答える