0

次の形式のテーブルがあります。

CREATE TABLE メッセージ (
    ID VARCHAR(40)、
    ソース VARCHAR(40)、
    dest VARCHAR(40),
    時間 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

最新のメッセージに対応するメッセージ ID とともに、すべての ID (src または dest フィールド) のリストを返すクエリを作成したいと考えています。このように使用する方法がよくわかりませんGROUP BY。さらに、このクエリは高速である必要があります (これが、src 用と dest 用の 2 つのクエリを単純に結合したくない理由です)。ただし、最終的には、どのように実行するかに関係なく、パフォーマンスが重要です。

サンプルデータ:

ID、送信元、送信先、時間
0, 0, 1, '2012-10-19 01:15:15'
1, 1, 0, '2012-10-20 01:15:15'
2, 0, 1, '2012-09-19 01:15:15'
3, 1, 0, '2012-04-20 01:15:15'
4、2、1、'2013-04-20 01:15:15'
5, 1, 0, '2012-04-20 01:15:15'

期待される出力:

id、人物
1、0
4、1
4、2

現在のクエリ:

SELECT m1.id,m1.src AS person FROM Messages m1 WHERE m1.time IS (SELECT MAX(time) FROM Messages m2 WHERE m2.src=m1.src OR m2.dest=m1.src)
連合
SELECT m1.id,m1.dest AS person FROM Messages m1 WHERE m1.time IS (SELECT MAX(time) FROM Messages m2 WHERE m1.dest=m2.dest OR m1.dest=m2.src)

ただし、5163 行のテーブルの場合、これには 19.99 秒かかります。クエリには 26,661,730 のステップがありました。

4

1 に答える 1

1

クエリの問題unionは相関サブクエリではなく、相関サブクエリにあると思われます。これは、トリックを使用して最大時間に関連付けられた ID を取得するアプローチです。時間の最後に id を追加してから、max()関数を適用します。

select substr(MAX(maxtime||maxtimeid), 19) as id, person
from (select src as person, substr(MAX(sent||CAST(id as varchar(20))), 19) as maxtimeid, MAX(sent) as maxtime
       from Messages
       group by src
       union all
      select dest as person, substr(MAX(sent||CAST(id as varchar(20))), 19) as maxtimeid, MAX(sent) as maxtime
       from Messages
       group by dest
     )
group by person

このクエリには集計がありますが、結合はありません。試してみて、パフォーマンスが向上するかどうかを確認してください。私はこれをテストしていないので、小さな構文エラーがあるかもしれないことに注意してください。

SQLite でのユニオンと外部結合の相対的なパフォーマンスはわかりません。ただし、これを次のように表現することもできます。

select (case when src.maxtime > dest.maxtime or dest.maxtime is null
             then src.maxtimeid
             else dest.maxtimeid
        end) as id,
       coalesce(src.person, dest.person) as person
from (select src as person, substr(MAX(sent||CAST(id as varchar(20))), 19) as maxtimeid, MAX(sent) as maxtime
       from Messages
       group by src
      ) src full outer join
      (select dest as person, substr(MAX(sent||CAST(id as varchar(20))), 19) as maxtimeid, MAX(sent) as maxtime
       from Messages
       group by dest
     ) dest
     on src.person = dest.person
于 2012-12-20T19:21:36.097 に答える