2

これは非常に基本的な質問のように思えますが、似たような質問がたくさんあります、何時間もの調査と試行錯誤の末、答えが見つかりません。これが繰り返される場合は、お詫び申し上げます。

次の 2 つの条件に基づいて、テーブルに参加したいと考えています。

column_1 = something_1 AND column_2 = max(something_2 未満のすべての可能なエントリ)。

私はこれを行うことができるはずだと思います:

Select t1.id, t2.id from table1 as t1
join
(select t1.id, max(t2.condition_2) as big_condition_2 from table1 as t1
join table2 as t2
on t2.condition_1 = t1.condition_1 and t2.condition_2 < t1.condition_2
group by t1.id) as t3
on t3.id = t1.id
join table2 t2
on t2.condition_1 = t1.condition_1 and t2.condition_2 = t3.big_condition_2

このクエリは現在 20 分後にタイムアウトになっており、タイムアウトを削除するのにどれくらいの時間がかかるかわかりません。私はそれが何か間違っていると確信しています。

各テーブルには平均で約 100 のタイプがcondition_1あり、各条件には約 4000 の異なるcondition_2値があります。したがって、各テーブルには 300k から 500k の行があります。その場合、サブクエリは約 2000 x 100 = 200k の結合を生成する必要があると見積もっていますが、これは無駄ですが、それほど長い遅延が発生するとは思いません。condition_1であり、intcondition_2あることに注意してくださいvarchar(21)

必要に応じて個別にまたは複数の参照フィールドのそれぞれにインデックスがありますが、t3 への結合ではインデックスが使用されないため、この t3 テーブルを生成したという事実により、処理が大幅に遅くなる可能性があります。

もっと基本的には、私が知りたいのは、これらの不要な結合をすべて実行せずに、結合する特定の値を選択できる方法があるかどうかです。つまり、(疑似コード)のようなことをします:

select t1.id, t2.id from table1 as t1
join table2 as t2
on t2.condition_1 = t1.condition_1
and t2.condition_2 = max(t2.condition_2 where t2.condition_2 > t1.condition_1)

よろしくお願いします。

アップデート

スティーブのリクエストで、クエリの説明を実行しようとしましたが、20 分後にタイムアウトになりました。次に、サブクエリ部分だけで説明を実行しようとしたところ、次の出力が得られました

UPDATE 2いくつかの新しいインデックスを追加し、サブクエリで Explain を再実行しました。結果は次のとおりです (より読みやすいように書式設定されています)。

id  select_type  table  type    possible_keys                           key                  key_len  ref                       rows    Extra
1   SIMPLE       esnap  index   ticker_id,ticker_id_2,date_time_GMT     PRIMARY              4        null                      20  
1   SIMPLE       ep     ref     primary_ticker_id,secondary_ticker_id   secondary_ticker_id  5        adr.esnap.ticker_id       1       Using where
1   SIMPLE       ets    ref     ticker_id,date_time_GMT                 ticker_id            5        adr.ep.primary_ticker_id  22430   Using where; Using index

説明としてesnaptableA、テーブルAとテーブルBを結合するために必要な中間テーブルであるテーブルですets。したがって、サブクエリは実際には次のとおりです。tableBep

select esnap.security_snap_id, max(ets.date_time_GMT) as snap_time from
equity_snapshots esnap
join equity_pairs ep on ep.secondary_ticker_id = esnap.ticker_id
join equity_trade_snaps ets on ets.ticker_id = ep.primary_ticker_id and
ets.date_time_GMT < esnap.date_time_GMT
group by esnap.security_snap_id

ここで、ticker_idはでintdate_time_GMTvarchar(21)です。

不可能なことを尋ねる?

さらに検討すると、サブクエリによって生成されるテーブルが大きすぎると思います。一致するペアはおよそ 100 あります ( condition_1)。各ペアには、tableA に約 6500 の異なる ID があり、tableB に 3500 の異なる ID があります。これは、グループ化の前に、約 100 * 6500 * (3500/2) = 11 億行が結合されることを意味します。

ジャワに頼る...

他の誰かがサブクエリを回避する方法を提案できない限り (つまり、「ALL less than, then group」ではなく、「max less than」にのみ結合する)、私はあきらめて Java を使用して全体をインポートするつもりだと思いますテーブル、そのことを行い、結果を mySql に出力します。これはすべて、もっと単純にする必要があるものには非常に時間がかかるようです....だから、誰かがより良い解決策を持っているなら、私に知らせてください.

4

1 に答える 1

0
SELECT t3.id, t2.id from (select t1.id,t1.condition_1, max(t2.condition_2) as big_condition_2 from table1 as t1
JOIN table2 as t2
on t2.condition_1 = t1.condition_1 and t2.condition_2 < t2.condition_2
group by t1.id,t1.condition_1 ) as t3

JOIN table2 t2
on t2.condition_1 = t3.condition_1 and t2.condition_2 = t3.big_condition_2

t2.condition_2 < t2.condition_2常に false はタイプミスの可能性があるため、条件を変更する必要があります。

于 2013-03-08T10:01:34.650 に答える