質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.64%

SQLを軽くしたい

解決済

回答 8

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 2,436

ByronHasegawa

score 259

下記のSQLを軽くしたいです。

読み込みが遅すぎて、結果が表示されません。

目的

高速に表示されるようにしたいです。
Advance custom fieldを使用して、その値などを取得しています。

//一覧情報取得
$result = $mydb->get_results("
SELECT post_title, id, post_name, m1.meta_value AS 'name_furigana', m2.meta_value AS 'photo_official', m3.meta_value AS 'position', m4.meta_value AS 'association', m5.meta_value AS 'number', m6.meta_value AS 'place', m7.meta_value AS 'graduate', m8.meta_value AS 'hobby', m9.meta_value AS 'motto', m10.meta_value AS 'greeting', m11.meta_value AS 'photo_working', m12.meta_value AS 'greeting_accident', m13.meta_value AS 'greeting_criminal'
FROM $mydb->posts
INNER JOIN $mydb->postmeta AS m1
    ON m1.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m2
    ON m2.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m3
    ON m3.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m4
    ON m4.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m5
    ON m5.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m6
    ON m6.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m7
    ON m7.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m8
    ON m8.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m9
    ON m9.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m10
    ON m10.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m11
    ON m11.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m12
    ON m12.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
INNER JOIN $mydb->postmeta AS m13
    ON m13.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
WHERE post_type = 'bio'
AND post_status = 'publish'
AND m1.meta_key = 'name_furigana'
AND m2.meta_key = 'photo_official'
AND m3.meta_key = 'position'
AND m4.meta_key = 'association'
AND m5.meta_key = 'number'
AND m6.meta_key = 'place'
AND m7.meta_key = 'graduate'
AND m8.meta_key = 'hobby'
AND m9.meta_key = 'motto'
AND m10.meta_key = 'greeting'
AND m11.meta_key = 'photo_working'
AND m12.meta_key = 'greeting_accident'
AND m13.meta_key = 'greeting_criminal'
AND post_name = 'myname'
");


//表示
foreach ($result as $value) {

$the_post_id = $value->id;

$sql_for_eyecatch = "
SELECT meta_value
FROM $mydb->postmeta
WHERE post_id = (SELECT meta_value FROM $mydb->postmeta WHERE post_id = $the_post_id AND meta_key = '_thumbnail_id') AND meta_key = '_wp_attached_file'";

$eyecatch = $mydb->get_var($sql_for_eyecatch);


$the_image = $value->photo_working;

$sql_for_imagework = "
SELECT guid
FROM $mydb->posts
WHERE ID = $the_image";

$imagework = $mydb->get_var($sql_for_imagework);


print('<li>'.$value->post_title.'</li></ul></div>
<h2 class="title">'.$value->post_title.'</h2>
<div class="profile-detail">
<div class="clearfix">
<div class="image1"><img width="300px" src="'.$eyecatch.'" alt="'.$value->post_title.'" /></div>
<div class="text">

<h5 class="name"><span class="wide">'.$value->post_title.'</span>('.$value->name_furigana.')</h5>
<table>

    <tbody>
    <tr>
        <th style="width: 120px;">テスト1</th>
        <td style="width: 230px;">'.$value->position.'</td>
    </tr>
    <tr>
        <th>テスト2</th>
        <td>'.$value->association.'</td>

    </tr>
    <tr>
        <th>テスト3</th>
        <td>'.$value->number.'</td>

    </tr>
    <tr>
        <th>テスト4</th>
        <td>'.$value->place.'</td>

    </tr>
    <tr>
        <th>テスト5</th>
        <td>'.$value->graduate.'</td>
    </tr>
    <tr>
        <th>テスト6</th>
        <td>'.$value->hobby.'</td>
    </tr>
    <tr>
        <th>テスト7</th>
        <td>'.$value->motto.'</td>
    </tr>
</tbody></table>
<img src="'.$imagework.'" alt="'.$value->post_title.'" />
</div>
</div>
<h4 class="clr">テスト8</h4>
<div class="greeting clearfix">
<p>'.$value->greeting.'</p>
</div>
<h4 class="clr">テスト9</h4>
<div class="greeting clearfix">
<p>'.$value->greeting_accident.'</p>
</div>
<h4 class="clr">テスト10</h4>
<div class="greeting clearfix">
<p>'.$value->greeting_criminal.'</p>
</div>
</div>');

}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • takotakot

    2016/02/19 14:58

    「具体的に何ができればよいか」をきちんと質問に書けば、よい SQL は得られると思います。

    キャンセル

回答 8

+7

SQLの実行計画を分析すれば、インデックスが効いているかどうかもわかると思うのでやるべき。

SQL Server: SQL Server クエリのパフォーマンスを最適化する
https://technet.microsoft.com/ja-jp/magazine/2007.11.sqlquery.aspx

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/18 16:48

    ありがとうございます。

    参考にさせて頂きました。

    キャンセル

+5

joinが多いのがパフォーマンスを下げているのでは?
SQLを実行できる環境がないので、イメージですが、

SELECT post_title, id, post_name
 , case
       when m1.meta_key = 'name_furigana' then m1.meta_value 
   end AS 'name_furigana'
 , case
       when m1.meta_key = 'photo_official' then m1.meta_value 
   end AS 'photo_official'
-- 中略
FROM $mydb->posts
INNER JOIN $mydb->postmeta AS m1
    ON m1.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
WHERE post_type = 'bio'
AND post_status = 'publish'
AND m1.meta_key in('name_furigana'
                 , 'photo_official'
                 , 'position'
                 , 'association'
                 , 'number'
                 , 'place'
                 , 'graduate'
                 , 'hobby'
                 , 'motto'
                 , 'greeting'
                 , 'photo_working'
                 , 'greeting_accident'
                 , 'greeting_criminal')
AND post_name = 'myname'


といった感じに変更されては?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/18 16:44

    ありがとうございます。

    実行するとなぜかコンテンツが繰り返し(いくつも)表示されます。

    キャンセル

  • 2016/02/19 14:56 編集

    ByronHasegawa 様
    速度はどうなりましたか?速度さえ良ければ、あとは繰り返しを消すように PHP で工夫するだけでは?

    以下追記: もしかして、あとは GROUP BY id するだけかな。

    キャンセル

  • 2016/02/19 15:40

    create table文と 修正したselect 文を提示できますか?

    キャンセル

  • 2016/02/22 10:03 編集

    こちらが修正したselect文です。


    SELECT post_title, id, post_name
    , case
    when m1.meta_key = 'name_furigana' then m1.meta_value
    end AS 'name_furigana'
    , case
    when m1.meta_key = 'position' then m1.meta_value
    end AS 'position'
    , case
    when m1.meta_key = 'association' then m1.meta_value
    end AS 'association'
    , case
    when m1.meta_key = 'number' then m1.meta_value
    end AS 'number'
    , case
    when m1.meta_key = 'place' then m1.meta_value
    end AS 'place'
    , case
    when m1.meta_key = 'graduate' then m1.meta_value
    end AS 'graduate'
    , case
    when m1.meta_key = 'hobby' then m1.meta_value
    end AS 'hobby'
    , case
    when m1.meta_key = 'motto' then m1.meta_value
    end AS 'motto'
    , case
    when m1.meta_key = 'greeting' then m1.meta_value
    end AS 'greeting'
    , case
    when m1.meta_key = 'photo_working' then m1.meta_value
    end AS 'photo_working'
    , case
    when m1.meta_key = 'greeting_accident' then m1.meta_value
    end AS 'greeting_accident'
    , case
    when m1.meta_key = 'greeting_criminal' then m1.meta_value
    end AS 'greeting_criminal'
    FROM $mydb->posts
    INNER JOIN $mydb->postmeta AS m1
    ON m1.post_id = $mydb->posts.ID /* テーブルを結合-カスタムフィールド */
    WHERE post_type = 'bio'
    AND post_status = 'publish'
    AND m1.meta_key in('name_furigana'
    , 'position'
    , 'association'
    , 'number'
    , 'place'
    , 'graduate'
    , 'hobby'
    , 'motto'
    , 'greeting'
    , 'photo_working'
    , 'greeting_accident'
    , 'greeting_criminal')
    AND post_name = 'name'
    GROUP BY m1.post_id
    HAVING COUNT(post_id) = 12;

    キャンセル

+2

こんにちは。
SQL Serverはあまり触ったことがないので、違っていたらご容赦ください。

WHERE句に指定している条件を、各INNER JOINの条件に追加してはどうでしょう?
扱うデータの量を最初に少なくしてあげれば、少しは軽くなるかと思います。

また、テーブル名のついていないカラム
post_typepost_statuspost_nameはどのテーブルに存在するんでしょうか?
ここも、テーブル名を指定してあげたほうが言いと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/18 16:42

    ありがとうございます。

    参考にさせて頂きました。

    キャンセル

+2

確かにサーバーがかわいそうなSQLではありますが、
やりたいことを推察するにそうSQLを直に書かずに
WordpressなのでWordpressの関数に任せられるものは任せた方が良いと思います。

<?php
$query = new WP_Query(array(
        'post_status' => "publish",
        'post_type' => "bio",
        'showposts' => -1,
));
$posts = $query->posts;
foreach ($posts as $post):
$meta = get_metadata('post', $post->ID);
?>
<li><?php echo $post->post_title;?></li></ul></div>
<h2 class="title"><?php echo $post->post_title;?></h2>
<div class="profile-detail">
<div class="clearfix">
<div class="image1"><img width="300px" src="<?php echo get_the_post_thumbnail_url($post);?>" alt="<?php echo $post->post_title;?>" /></div>
<div class="text">
<h5 class="name"><span class="wide"><?php echo $post->post_title;?></span>(<?php echo $meta['name_furigana'][0];?>)</h5>
<table>
    <tbody>
    <tr>
        <th style="width: 120px;">テスト1</th>
        <td style="width: 230px;"><?php echo $meta['position'][0];?></td>
    </tr>
<!-- 略 -->
    </tbody>
</table>
<img src="<?php echo get_the_post_thumbnail_url($post, 'full');?>" alt="<?php echo $post->post_title;?>" />
</div>
</div>
<h4 class="clr">テスト8</h4>
<div class="greeting clearfix">
<p><?php echo $meta['greeting'][0];?></p>
</div>
<!-- 略 -->
</div>
<?php endforeach;?>

ちなみに get_the_post_thumbnail_url() はWordpressのversion4.4以降でないと使えません。
ですので未満の場合はget_the_post_thumbnail()で。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/18 16:46 編集

    ありがとうございます。

    別のデーターベースから読み込んでいるため、SQLを使うしかないです。

    キャンセル

+2

postmetaは巨大なキーバリューテーブルになっているように見えます。
ですので、postmetaをkey単位で分割した後にJOINするようにしてはどうでしょうか?

SELECT m0.post_title, m0.id, m0.post_name, m1.meta_value AS 'name_furigana', m2.meta_value AS 'photo_official', m3.meta_value AS 'position', m4.meta_value AS 'association', m5.meta_value AS 'number', m6.meta_value AS 'place', m7.meta_value AS 'graduate', m8.meta_value AS 'hobby', m9.meta_value AS 'motto', m10.meta_value AS 'greeting', m11.meta_value AS 'photo_working', m12.meta_value AS 'greeting_accident', m13.meta_value AS 'greeting_criminal'
FROM (SELECT post_title, id, post_name FROM $mydb->posts WHERE post_type = 'bio' AND post_status = 'publish') AS m0
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'name_furigana') AS m1
    ON m1.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'photo_official') AS m2
    ON m2.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'position') AS m3
    ON m3.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'association') AS m4
    ON m4.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'number') AS m5
    ON m5.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'place') AS m6
    ON m6.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'graduate') AS m7
    ON m7.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'hobby') AS m8
    ON m8.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'motto') AS m9
    ON m9.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'greeting') AS m10
    ON m10.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'photo_working') AS m11
    ON m11.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'greeting_accident') AS m12
    ON m12.post_id = m0.id /* テーブルを結合-カスタムフィールド */
INNER JOIN (SELECT post_id, meta_value FROM $mydb->postmeta WHERE meta_key = 'greeting_criminal') AS m13
    ON m13.post_id = m0.id /* テーブルを結合-カスタムフィールド */
WHERE post_name = 'myname'


最後に本当の検索キー?のpost_nameで絞り込んでいます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/18 16:50

    ありがとうございます。

    取得したい値(INNER JOIN)が増えると読み込みも重くなるのですか??

    現在はこの提示して頂いたソースでどうにか表示はできるようになりましたが、やはり表示に3分くらいはかかります。

    キャンセル

  • 2016/02/19 15:12

    INNER JOIN が増えると、結合した表を作ろうとするので、重くなりますよ。

    キャンセル

  • 2016/02/22 09:54

    そうなんですね。
    無知ですみません。。。

    ありがとうございます。

    キャンセル

+2

postsテーブルに検索用のインデックスは作られていますか?
もし作られていないようでしたらWHERE条件で指定している項目でインデックスを作ってみてはいかがでしょうか?

ALTER TABLE posts ADD INDEX posts_idx1(post_type, post_status, post_name);

インデックス作成前後の速度の違いと作成後の実行計画も見てみたいです。
(select文の前にexplainをつけて実行。 explain select ~)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/03 16:52

    ありがとうございます。

    参考にさせて頂き、使用しました。

    キャンセル

checkベストアンサー

+1

JOINを排除したSQLをつくってみました。
「JOINした場合、100件のテーブルと200件のテーブルをJOINした場合
100×200 =2万件のデータが、メモリにロードされてから、条件に合ったものを
探しているとイメージすると、JOINがどれだけ遅くなる原因になるか想像できる思います。」
$result = $mydb->get_results("
SELECT 
    m0.post_title, 
    m0.id, 
    m0.post_name, 
    (select m1.meta_value  from $mydb->postmeta m1  where m1.post_id  = m0.id and m1.meta_key  = 'name_furigana' ) AS 'name_furigana', 
    (select m2.meta_value  from $mydb->postmeta m2  where m2.post_id  = m0.id and m2.meta_key  = 'photo_official' ) AS 'photo_official', 
    (select m3.meta_value  from $mydb->postmeta m3  where m3.post_id  = m0.id and m3.meta_key  = 'position' )  AS 'position', 
    (select m4.meta_value  from $mydb->postmeta m4  where m4.post_id  = m0.id and m4.meta_key  = 'association' )  AS 'association', 
    (select m5.meta_value  from $mydb->postmeta m5  where m5.post_id  = m0.id and m5.meta_key  = 'number' )  AS 'number', 
    (select m6.meta_value  from $mydb->postmeta m6  where m6.post_id  = m0.id and m6.meta_key  = 'place' )  AS 'place', 
    (select m7.meta_value  from $mydb->postmeta m7  where m7.post_id  = m0.id and m7.meta_key  = 'graduate' )  AS 'graduate', 
    (select m8.meta_value  from $mydb->postmeta m8  where m8.post_id  = m0.id and m8.meta_key  = 'hobby' )  AS 'hobby', 
    (select m9.meta_value  from $mydb->postmeta m9  where m9.post_id  = m0.id and m9.meta_key  = 'motto' )  AS 'motto', 
    (select m10.meta_value from $mydb->postmeta m10 where m10.post_id = m0.id and m10.meta_key = 'greeting' )  AS 'greeting', 
    (select m11.meta_value from $mydb->postmeta m11 where m11.post_id = m0.id and m11.meta_key = 'photo_working' )  AS 'photo_working', 
    (select m12.meta_value from $mydb->postmeta m12 where m12.post_id = m0.id and m12.meta_key = 'greeting_accident' )  AS 'greeting_accident', 
    (select m13.meta_value from $mydb->postmeta m13 where m13.post_id = m0.id and m13.meta_key = 'greeting_criminal' )  AS 'greeting_criminal'
FROM ( select post_title, id, post_name from $mydb->posts where post_type = 'bio' and AND post_status = 'publish' AND AND post_name = 'myname' ) AS m0
");

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/03 16:53

    とても分かりやすい回答ありがとうございます。

    とても、早く読み込まれました!

    ありがとうございます!

    キャンセル

+1

疑問点: $mydb->postmeta には、どのような index が張られているか。
「実行計画を分析」の結果はどうなったか。

私もイメージだけで、申し訳ないです。方向性としては、Orlofsky 様の方向が一番良さそうです。
一発でやろうとしてもいいですが、意図を考えると

SELECT post_id FROM $mydb->postmeta
WHERE meta_key
                 in('name_furigana'
                 , 'photo_official'
                 , 'position'
                 , 'association'
                 , 'number'
                 , 'place'
                 , 'graduate'
                 , 'hobby'
                 , 'motto'
                 , 'greeting'
                 , 'photo_working'
                 , 'greeting_accident'
                 , 'greeting_criminal')
GROUP BY post_id
HAVING COUNT(post_id) = 13;


で、postmeta について条件を満たす id 一覧を作ってから考えた方が楽だと思います。
この id を var_dump して、条件を満たしていそうであれば(正しい id 集合で、

WHERE post_type = 'bio'
AND post_status = 'publish'


以外を満たしていれば)、これをサブクエリに使って絞り込む方がずっと高速だと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/01 11:22

    申し訳ありません。

    まだ公開しているサイトではないので、サイトのリンクをお伝えできません。

    キャンセル

  • 2016/03/01 11:48

    クエリの結果を求めているのであって、サイトのリンクは求めていません。

    キャンセル

  • 2016/03/01 13:08

    post_idの結果が表示されます。

    post_id
    745
    846
    848
    884
    885
    886
    887
    892
    893
    894
    895
    896
    897
    898
    900
    902
    903

    提示するものが違ったらすみません。。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる