2017-03-23 3 views
2

eine Abfrage gegeben, select * from ... (der Teil der CTAS Aussage sein könnte)Wie man eine ganzzahlige ID zum Abfrageergebnis hinzufügt - __efficiently__?

Das Ziel ist, eine zusätzliche Spalte, ID, wo ID ist eine eindeutige ganze Zahl hinzuzufügen.

select ... as ID,* from ... 

Ps.s.

  • ID muss nicht fortlaufend sein (es könnte Lücken)
  • Die ID könnte beliebig sein

(keine bestimmte Reihenfolge innerhalb der Ergebnismenge darstellen müssen)

row_number löst das Problem logisch -

select row_number() over() as ID,* from ... 

Das Problem ist, dass zumindest jetzt global row_number (keine Partition von) mit einem einzigen Reducer (Bienenstock)/Aufgabe (Funken) implementiert wird.

+1

Beginnend mit Hive 2.2 können Sie eine UUID anstelle einer Sequenz generieren - https://issues.apache.org/jira/browse/HIVE-12721 –

+1

Und da die Hive UUID-Funktion einfach 'java.util.UUID 'aufruft. randomUUID(). toString() 'Sie sollten etwas Ähnliches mit' reflect 'in jeder Hive-Version> https://github.com/apache/hive/blob/master/ql/src/java/org/apache tun können /hadoop/hive/ql/udf/UDFUUID.java –

+0

Da war ich schon, fertig :-). UUID ist 36 Bytes Vs. 4 von INT oder 8 von BIGINT. Sie zahlen dafür im Speicher und in jeder anderen Operation - WHERE, GROUP BY, JOIN, ORDER BY usw. –

Antwort

1

Bienenstock

set mapred.reduce.tasks=1000; 
set hivevar:buckets=10000; 

hivevar:buckets sollte genug relativ zu der Anzahl der Reduzierer (mapred.reduce.tasks) hoch sein, so dass die Reihen gleichmäßig verteilt werden, die zwischen reduziert.


select 1 + x + (row_number() over (partition by x) - 1) * ${hivevar:buckets} as id 
     ,t.* 

from (select t.* 
       ,abs(hash(rand())) % ${hivevar:buckets} as x  

     from t 
     ) t 

funkt sql

select 1 + x + (row_number() over (partition by x) - 1) * 10000 as id 
     ,t.* 

from (select t.* 
       ,abs(hash(rand())) % 10000 as x  

     from t 
     ) t 

Sowohl für den Bienenstock und funken sql

Die rand() verwendet, um eine gute Verteilung zu erzeugen.
Wenn Sie in Ihrer Abfrage bereits eine Spalte/Kombination von Spalten mit einer guten Verteilung haben (möglicherweise eindeutig, kein Muss), können Sie sie stattdessen verwenden, z. -

select 1 + (abs(hash(col1,col)) % 10000) 
     + (row_number() over (partition by abs(hash(col1,col)) % 10000) - 1) * 10000 as id 
     ,t.* 

from t 
+1

Randnotiz: Warum Hash ein zufälliger Wert? Da Hashing deterministisch ist, ändert das nicht die Wahrscheinlichkeit einer Kollision ... –

+0

Wenn Sie Spalten mit einer bekannten guten Verteilung haben, können Sie sie stattdessen verwenden, aber achten Sie darauf, dass Sie Werte verwenden, die möglicherweise verzerrt sind. –

1

Wenn Sie Funken SQL Ihre beste Wette verwenden wäre die eingebaute Funktion verwendet

monotonically_increasing_id

, die in einer separaten Spalte eindeutigen Zufall-ID erzeugt. Und wie Sie gesagt haben, brauchen Sie es nicht, um sequentiell zu sein, also sollte dies idealerweise Ihre Anforderung erfüllen.

0

prüfen diese Lösung von Manoj Kumar: https://github.com/manojkumarvohra/hive-hilo

  • eine Stateful UDF geschaffen wird, die eine HALLO/LO hält Zähler Inkrement der Sequenzen.
  • Der HI-Wert wird als atomar lang im Zoowächter gespeichert.
  • Der HI-Wert wird inkrementiert & abgerufen für jeden n LO (Standard 200) Iterationen.
  • Die UDF unterstützt ein einzelnes String-Argument. Dies ist der Sequenzname , der zum Verwalten von zNodes in zookee verwendet wird.

Verbrauch:

FunctionName(sequenceName, lowvalue[optional], seedvalue[optional]) 
Verwandte Themen