MySQL5.0.45
PHPから呼び出しています。
テーブル my_site 約1万データ
テーブル my_exclude 約1万データ
LEFT JOINが原因だと思いますが、良い方法はないでしょうか。
select my_site.id as id, my_site.url as url, my_site.name as name from my_site LEFT JOIN my_exclude ON my_site.url=my_exclude.url && my_exclude.usrid=10000 where my_site.usrid!=10000 && my_exclude.url IS NULL order by rand() limit 2;
やりたい事は、
「my_siteからランダムで2行URLを抜き出す」です。
そのときに、「my_excludeにはユーザーごと(usrid)に固有の除外URLを複数指定でき、対象URLからは省く」必要があります。
これをLEFT JOINで解決していますが、他の早い方法に書き換えたいと思います。
PHP側での解決でも構いませんが、アドバイスどうぞよろしくお願いいたします。
まずはお願いなのですが、
テーブルの構造やインデックスキーの張り方など
何も判らないと原因の特定は難しくなりますので、必須だとご記憶ください。
不適当な回答が集まっても混乱をきたしますから、私への返信欄か、
あるいは、コメント欄を開く設定に変更してコメント欄)に、
書き加えておくことを勧めます。
SQL文にorder by rand()
がランダム取り込みのために入っているから、必要ない(必要なのですが)全ての行にrand()の実行結果を付加して、ソートしているからだと勝手に妄想。
order by rand()
取り除いてはやいキーが付いているフィールドで普通の順番にして、
SQL発行後、n=MAXレコード数分の乱数を計算してから、mysql_field_seek とかで移動して値を取得、
2個目がほしいので、先頭行に忘れずカーソルを戻して、乱数発行、レコード移動、値の取得で2行ランダムっぽく取り出すとか。
以上、三流プログラマーの妄想でした。解決策の糸口・何かの参考となれば幸いです。
ダミーURL http://www.mysql.gr.jp/
アドバイス本当にありがとうございます。
実際にrand()をはずしてみましたが、実行速度はほとんど変化ありませんでした。
キーを特に意識していないのですが、その点が問題でしょうか。
ご指摘ありがとうございます。
mysql> describe my_site;
+--------------+--------------+------+-----+---------+----------------+
+--------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| usrid | int(11) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
| url | varchar(255) | YES | | NULL | |
| hour | varchar(13) | YES | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
mysql> describe my_exclude;
+----------+--------------+------+-----+---------+----------------+
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| usrid | int(11) | NO | | 0 | |
| url | varchar(255) | YES | | NULL | |
+----------+--------------+------+-----+---------+----------------+
このように作成しています。