2

私は依存クエリであり、多くの実行時間がかかるこのクエリを持っています

SELECT
  u.id,
  u.user_name,
  ifnull((select longitude from map where user_id = u.id order by map_id desc limit 1 ),0) as Longitude,
  ifnull((select latitude from map where user_id = u.id order by map_id desc limit 1 ),0) as Longitude,
  (select  created  from map  where user_id = 1  order by created desc   limit 1) as LatestTime
FROM users as u
WHERE id IN(SELECT
          user1_id FROM relation
        WHERE users.id = 1)
ORDER BY id;

私は(依存)でこのクエリを試しました

SELECT
  u.id,
  u.user_name,
  m.map_id,
  m.longitude,
  m.latitude,
  m.Date as created
FROM users as u
  left join (select
           map_id,
           longitude,
           latitude,
           user_id,
           max(created) as `Date`
         from map
         group by user_id) as m
    on m.user_id = u.id
WHERE id IN(SELECT
          user1_id FROM relation
        WHERE users.id = 1)
ORDER BY id;

問題は、最初のクエリが依存しており、正常に動作しているが、実行に時間がかかることです。2 番目のクエリの問題は、最新の作成時間を取得していないことです。今、私はこのクエリを最適化したいと考えています。テーマは、サブクエリで最初にグループを作成し、次に各グループの最後のレコードを取得しようとすることです。これがテーブル構造です。

users : id , user_name
map   : map_id ,  user_id ,longitude , latitude, created 
relations : id , user1_id , user2_id , relation
4

1 に答える 1

5

パフォーマンスが必要な場合、句のサブクエリSELECTは確かに面倒であり、追放する必要があります:)

この部分を次のように書き換えることができます。

SELECT
    u.id,
    u.user_name,
    ifnull((select longitude from map where user_id = u.id order by map_id desc limit 1 ),0) as Longitude,
    ifnull((select latitude from map where user_id = u.id order by map_id desc limit 1 ),0) as Longitude,
    (select  created  from map  where user_id = 1  order by created desc   limit 1) as LatestTime
FROM users as u

の:

SELECT
    u.id,
    u.user_name,
    COALESCE(m1.longitude, 0) as longitude,
    COALESCE(m1.latitude, 0) as latitude
FROM users u
LEFT JOIN map m1 ON m1.user_id = u.id
LEFT JOIN map m2 ON m2.user_id = m1.user_id AND m2.map_id > m1.map_id
WHERE m2.map_id IS NULL

この回答でクエリ構造の簡単な説明を書きました。より読みやすく、サブクエリがなく、パフォーマンスが向上するため、習得するのに非常に優れたトリックです。

私はINまだその部分を見ていませんが、上記が役に立たなかった場合はそうします.

Edit1:作成日を抽出し、代わりに MAX() を使用できます。

SELECT
    u.id,
    u.user_name,
    COALESCE(m1.longitude, 0) as longitude,
    COALESCE(m1.latitude, 0) as latitude,
    created.LatestTime
FROM (SELECT MAX(created) FROM map WHERE user_id = 1) created
INNER JOIN users u ON TRUE
LEFT JOIN map m1 ON m1.user_id = u.id
LEFT JOIN map m2 ON m2.user_id = m1.user_id AND m2.map_id > m1.map_id
WHERE m2.map_id IS NULL
于 2012-06-22T13:12:59.823 に答える