2

完了するまでに長い時間がかかりますが、収集した情報をすばやく引き出すことができれば幸いです.

SELECT *
FROM releases
WHERE (artist IN (SELECT artist FROM artist_love WHERE user='Quickinho')
OR
label IN (SELECT label FROM label_love WHERE user='Quickinho')
OR
id IN (SELECT release_id FROM charts_extended WHERE artist IN (SELECT dj FROM dj_love WHERE user='Quickinho'))
OR
id IN (SELECT artist FROM releases WHERE id IN (SELECT release_id FROM charts_extended WHERE user='Quickinho'))
OR
id IN (SELECT label FROM releases WHERE id IN (SELECT release_id FROM charts_extended WHERE user='Quickinho')))
AND
id NOT IN (SELECT release_id FROM charts_extended WHERE user='Quickinho')
ORDER BY date DESC
LIMIT 0,102
4

8 に答える 8

8

副選択を避ける (ただし、テストされていないため、タイプミスは許してください)

SELECT *
FROM releases
LEFT OUTER JOIN artist_love ON releases.artist = artist_love.artist AND artist_love.user = 'Quickinho'
LEFT OUTER JOIN label_love ON releases.label = label_love.label AND label_love.user = 'Quickinho'
LEFT OUTER JOIN charts_extended ON releases.id = charts_extended.release_id
LEFT OUTER JOIN dj_love ON charts_extended.artist = dj_love.dj AND dj_love.user = 'Quickinho'
LEFT OUTER JOIN releases releases1 ON releases.id = releases1.artist
LEFT OUTER JOIN charts_extended charts_extended1 ON charts_extended1.artist = releases1.id AND charts_extended1.user = 'Quickinho'
LEFT OUTER JOIN releases releases2 ON releases.id = releases2.label
LEFT OUTER JOIN charts_extended charts_extended2 ON charts_extended2.artist = releases2.id AND charts_extended2.user = 'Quickinho'
LEFT OUTER JOIN charts_extended charts_extended3 ON charts_extended3.release_id = releases.id AND charts_extended3.user = 'Quickinho'
WHERE (artist_love.user IS NOT NULL
OR label_love.user IS NOT NULL
OR dj_love.user IS NOT NULL
OR charts_extended1.user IS NOT NULL
OR charts_extended2.user IS NOT NULL)
AND charts_extended3.user IS NULL
于 2012-10-13T20:10:36.353 に答える
4

他の人が提供した最適化されたクエリがまだ十分に高速でない可能性があります。

元のクエリの実行に 120 秒かかり、最適化された最適なクエリでも 30 秒かかるとします。ただし、5 秒以上の応答時間が必要です。あなたは何ができますか?

事前入力!

毎時間など、定期的に実行されるcron ジョブによってトリガーされるクエリを実行します。次のようなクエリを使用します。INSERT SELECT

INSERT INTO releases_queried
SELECT -- your query (your original one or one of the optimized ones)

MySQL マニュアル INSERT-SELECTを参照してください。次に、から結果を取得します

SELECT * FROM releases_queried

ミリ秒以内にすぐに。これは、応答時間を改善するためのよく知られた手法です。クエリに必要なデータが常に利用可能であれば、うまく機能します。

実世界での使用

StackOverflow 自体には、要求に応じてではなく非同期で実行される多くの複雑なクエリがあります。バッジは訪問ごとに計算されるのではなく、cron によって計算されます。

于 2012-10-13T20:31:07.627 に答える
3
...from releases
WHERE (artist IN (SELECT artist FROM artist_love WHERE user='Quickinho')

JOIN代わりに使用することをお勧めしますIN (SELECT..)

次のようなことができます

select r.* from releases r, artist_love al 
where r.artist = al.artist and al.user='Quickinho'
于 2012-10-08T10:37:41.787 に答える
2

IN() および NOT IN() サブクエリは最適化が不十分です
。MySQL はサブクエリを外部クエリの各行の従属サブクエリとして実行します。これは、MySQL 5.5 以前のバージョンで深刻なパフォーマンスの問題を引き起こす原因となることがよくあります。クエリはおそらく、それぞれ JOIN または LEFT OUTER JOIN として書き直す必要があります。

選択する *

* ワイルドカードを使用してすべての列を選択すると、テーブルのスキーマが変更された場合にクエリの意味と動作が変化し、クエリで大量のデータが取得される可能性があります。

于 2012-10-11T07:04:18.013 に答える
1

まず、JOIN 関係で使用されるすべてのフィールドをインデックス化します。

次に、このクエリを試してください-

SELECT
  r.*
FROM
  releases r
LEFT JOIN (SELECT artist FROM artist_love WHERE user='Quickinho') al
  ON al.artist = r.artist
LEFT JOIN (SELECT label FROM label_love WHERE user='Quickinho') ll
  ON ll.label = r.label
LEFT JOIN (
    SELECT release_id FROM charts_extended ce
    INNER JOIN (SELECT dj FROM dj_love WHERE user='Quickinho') djl
      ON djl.dj = ce.artist
    ) ce
  ON r.id = ce.release_id
LEFT JOIN (
    SELECT artist FROM releases r
    INNER JOIN (SELECT release_id FROM charts_extended WHERE user='Quickinho') ce
      ON r.id = release_id
  ) r2
  ON r2.artist = r.id OR r2.label = r.id

LEFT JOIN (SELECT release_id FROM charts_extended WHERE user='Quickinho') ce2
  ON ce2.release_id = r.id

WHERE
  (al.artist IS NOT NULL OR ll.label IS NOT NULL OR ce.release_id IS NOT NULL OR r2.id IS NOT NULL)
  AND ce2.release_id IS NULL
GROUP BY
  r.id
于 2012-10-12T06:39:08.500 に答える
1

key_cacheSQL Partition、を検索できますperformance tuning

于 2012-10-16T09:40:38.953 に答える
1

を使用しJOINてパフォーマンスを向上させることができます。JOIN では、すべてのクエリを実行し、すべてのデータをロードして処理を行うサブクエリとは異なり、RDBMS はクエリに適した実行計画を作成できます。

于 2012-10-17T17:24:50.453 に答える
1

Kickstart の解決策は正しい考えです (ただし、可能であれば USER にも JOIN することをお勧めしますが、「user = 'Quickinho'」を何度も表示させることはお勧めできません)。次に、次のフィールドの一部またはすべてにインデックスを追加することを検討してください。 :

  • artist_love.artist
  • label_love.label
  • charts_extended.release_id
  • dj_love.dj
  • リリース.アーティスト
  • リリース.ラベル
  • charts_extended.release_id

私はあなたがこれで何をしようとしているのかを考えることができるとは言えませんが. より良い解決策がある可能性があります。

于 2012-10-16T07:01:24.013 に答える