web-dev-qa-db-ja.com

JOIN with BETWEENの代替

BETWEEN条件に基づいてJOINする2つのテーブルがあります。

_Table 1_は小さく、約1500レコードで、_Table 2_は4,000万レコードです。 Table1には、データ型bigintの列が1つだけあり、8列の_Table2_があります。これら2つのテーブルをBETWEEN条件で結合する必要があります。

フォローしてみましたが、_Table1_では1レコード、_Table2_では4,000万レコードと遅くなりました。

クエリ:

_SELECT t1.cola AS [InputValue],t2.cola,t2.colb,t2.colc,t2.cold,t2.code
FROM table2 t2 
INNER JOIN table1 t1 ON t1.cola BETWEEN t2.cola AND t2.colb ;
_

インデックス作成:

  1. CREATE NONCLUSTERED INDEX NCIX_Table1_Cola ON table1(cola)
  2. CREATE NONCLUSTERED INDEX NCIX_Table2_Col_a_b ON table2(cola,colb)

上記のクエリは、_table1_の1つのレコードだけで30秒かかり、_table2_の4,000万レコードでした。前述のように、_table1_で1500件を超えるレコードを取得すると、さらに遅くなります。間または適切なインデックス付けの代替手段を実行する必要がありますか?

Edit:サンプルデータを追加しました。

表1:

_cola
---------------
12
145
34
90
88990
987611
55
...
..
......1500 rows
_

表2:

_cola    colb    colc    cold    cole
-------------------------------------
0       10      c1      d1      e1
11      20      c2      d2      e2
21      40      c3      d3      e3
41      60      c4      d4      e4
61      100     c5      d5      e5
101     1000    c6      d6      e6
1001    10000   c7      d7      e7
10001   200000  c8      d8      e8
...... 
......40 millions records
_

期待される結果:

_InputValue  cola    colb    colc    cold    cole
--------------------------------------------------
12          11      20      c2      d2      e2
145         101     1000    c6      d6      e6
34          21      40      c3      d3      e3
.....
_

SQL Fiddle: Link

1
MAK

私は同様の問題に直面しました-SQLはcolaとcolbが範囲であることを「認識」しておらず、次の行のcolaは常に現在の行のcolbよりも大きいため、その間はあまり役に立ちません。最初に一致するコーラ、他のコーラもチェックし続けます。 cross applyを使用してmax(table2.cola) <= table1.colaを検索し、追加を確認するクエリをお勧めしますwhere table2.colb >= table1.colaこのようなもの

SELECT      t1.cola AS [InputValue]
           ,t2.cola
           ,t2.colb
           ,t2.colc
           ,t2.cold
           ,t2.code
FROM        table1 t1
CROSS APPLY (   SELECT   TOP 1
                         t2.cola
                        ,t2.colb
                        ,t2.colc
                        ,t2.cold
                        ,t2.code
                FROM     table2 t2
                WHERE    t1.cola >= t2.cola
                         AND t1.cola <= t2.colb
                ORDER BY t2.cola DESC ) t2;
1