2016-07-05 8 views
0

Ich habe zwei Tabellen, eine ist a (1000 Zeilen), eine andere ist b (70 Millionen Zeilen).Wie kann man Nichtgleichheit Join in Hive optimieren?

gibt es zwei Feld starttime, endtime in Tabelle a und ein Feld in der Tabelle timeb.

Ich benutze mapjoin abfragen:

select /*+ MAPJOIN(a) */ a.starttime,a.endtime, b.time 
from a join b 
where b.time between a.starttime and a.endtime; 

aber sehr sehr langsam ausgeführt werden. mapreduce Job bleibt immer auf 0%.

Haben Sie eine andere Möglichkeit zu optimieren?

Antwort

0

Eine Methode ist nur zu erweitern a, um eine Zeile für jeden Tag zu haben.

Eine andere Methode besteht darin, eine Interleaving-Technik zu verwenden. Dies setzt voraus, dass a die Zeit wirklich partitioniert, so dass es keine Überlappungen oder Lücken gibt. Und das b hat einen Primärschlüssel.

Also, für jeden id in b können Sie die entsprechende Startzeit in a erhalten:

select id, time, max(starttime) over (order by time, priority) as a_starttime 
from ((select b.id, b.time, null as starttime, 2j as priority from b) union all 
     (select null, a.starttime, a.starttime, 1 as priority from a) 
    ) ab; 

Dann können Sie diese mit einem Equijoin verwenden:

select id, time, a.starttime, a.endtime 
from (select id, time, max(starttime) over (order by time, priority) as a_starttime 
     from ((select b.id, b.time, null as starttime, 2j as priority from b) union all 
      (select null, a.starttime, a.starttime, 1 as priority from a) 
      ) ab 
    ) ab join 
    a 
    on ab.a_starttime = a.starttime; 

Hinweis: Diese Technik funktioniert hat gut auf anderen Datenbanken. Ich hatte nicht die Gelegenheit, es auf Hive zu versuchen.

+0

Vielen Dank für Ihre Antwort! In der Tat, es gibt viele Felder in zwei Tabellen, die Verwendung von Interleaving-Technik sieht wie lästig und unbequem aus, ist es richtig? Gibt es einen anderen Weg für diesen Fall? – Guo

+0

@Guo. . . Nicht dass ich in Hive leicht daran denken kann. –