0

私は大きな mysql クエリ (mysql 5.0) で頭がいっぱいです。誰かが助けてくれることを願っています。

前に、結合されたクエリから個別の値を取得する方法を尋ねました mysql は、結合されたクエリの個別の値に対してのみカウントします

私が得た応答(join asでサブクエリを使用)

選択する *
メディアから
内部結合
     ( uid を選択
     users_tbl から
     制限 0,30) マップ
  on map.uid = m.uid
内部結合 users_tbl u
  u.uid = m.uid で

残念なことに、私のクエリはより手に負えなくなりました。クエリを実行しても、派生クエリで使用できるインデックスがないため、派生テーブルへの結合に時間がかかりすぎます。

私のクエリは次のようになります

SELECT mdate.bid、mdate.fid、mdate.date、mdate.time、mdate.title、mdate.name、
       mdate.address, mdate.rank, mdate.city, mdate.state, mdate.lat, mdate.`long`,
       外部リンク、
       ext.source、ext.pre、meta、mdate.img
外部から
右外部結合 (
  SELECT media.bid,
         media.date、media.time、media.title、users.name、users.img、users.rank、media.address、
         media.city, media.state, media.lat, media.`long`,
         GROUP_CONCAT(tags.tagname SEPARATOR ' | ') AS メタ
  メディアから
  media.bid = users.bid でユーザーに参加
  users.bid=tags.bid の LEFT JOIN タグ
  WHERE `long` BETWEEN -122.52224684058 AND -121.79760915942
    AND lat BETWEEN 37.07500915942 AND 37.79964684058
    AND 日付 = '2009-02-23'
  GROUP BY media.bid、media.date
  ORDER BY media.date, users.rank DESC
  リミット 0、30
) mdate ON (mdate.bid = ext.bid AND mdate.date = ext.date)

ふぅ!

SO、ご覧のとおり、私の問題を正しく理解していれば、インデックスのない派生テーブルが 2 つあります (そして、何らかの形で Join ステートメントを台無しにした可能性があることは否定しませんが、さまざまなタイプをいじり続けましたが、これで終わりですか?私が望んでいた結果を私に与えてください)。

インデックスを利用できるようにする、これに似たクエリを作成する最良の方法は何ですか? あえて言いますが、実際には、後日ミックスに追加するテーブルがもう 1 つあります。

現在、私のクエリは完了するまでに 0.8 秒かかりますが、インデックスを利用できれば、これはかなり高速になると確信しています。

4

3 に答える 3

1

新たに始める:

質問 - なぜ media.bid と media.date の両方でグループ化するのですか? 入札には複数の日付のレコードを含めることができますか?

試してみる簡単なバージョンは次のとおりです。

SELECT 
    mdate.bid,
    mdate.fid,
    mdate.date,
    mdate.time,
    mdate.title,
    mdate.name, 
    mdate.address,
    mdate.rank,
    mdate.city,
    mdate.state,
    mdate.lat,
    mdate.`long`,
    ext.link, 
    ext.source,
    ext.pre, 
    meta,
    mdate.img,
    (   SELECT GROUP_CONCAT(tags.tagname SEPARATOR ' | ')
        FROM tags 
        WHERE ext.bid = tags.bid
        ORDER BY tags.bid GROUP BY tags.bid
    ) AS meta

FROM 
    ext

LEFT JOIN
    media ON ext.bid = media.bid AND ext.date = media.date

JOIN
    users ON ext.bid = users.bid

WHERE 
    `long` BETWEEN -122.52224684058 AND -121.79760915942
    AND lat BETWEEN 37.07500915942 AND 37.79964684058
    AND ext.date = '2009-02-23'
    AND users.userid IN
    (    
        SELECT userid FROM users ORDER BY rank DESC LIMIT 30
    )

ORDER BY 
    media.date, 
    users.rank DESC
    LIMIT 0, 30
于 2009-02-23T19:52:01.693 に答える
1

まず、 、 、 のインデックスを確認しext(bid, date)users(bid)くださいtags(bid)。実際にそれらがあるはずです。

しかし、それがあなたにほとんどの問題を引き起こしているようですLONG。andを としてLAT保持し、この列にa を作成して、次のようにクエリを実行する必要があります。LONGLAT(coordinate POINT)SPATIAL INDEX

WHERE MBRContains(@MySquare, coordinate)

何らかの理由でスキーマを変更できない場合はdate、最初のフィールドとしてインクルードする追加のインデックスを作成してみてください。

CREATE INDEX ix_date_long ON media (date, `long`)
CREATE INDEX ix_date_lat ON media (date, lat)

dateこれらのインデックスは、 の完全一致検索と の範囲検索を組み合わせて使用​​するため、クエリに対してより効率的ですaxes

于 2009-02-23T20:08:54.557 に答える
0

パフォーマンスを、選択ごとに一時テーブルを使用し、それらのテーブルを結合することと比較したい場合があります。

テーブル作成 #whatever テーブル作成 #whatever2

#whatever select... に挿入 #whatever2 select... に挿入

から選択 #whatever 結合 #whatever 2

....

ドロップ テーブル #whatever ドロップ テーブル #whatever2

システムに完全なテーブルを保持するのに十分なメモリがある場合、これははるかに高速に機能する可能性があります。データベースの大きさによって異なります。

于 2009-02-24T05:45:32.797 に答える