Aralık birleştirme iyileştirmesi
aralık birleştirme, aralık veya aralık çakışma koşulundaki bir nokta kullanılarak iki ilişki birleştirildiğinde oluşur. Databricks Runtime'daki aralık birleştirme optimizasyon desteği, sorgu performansında kat kat iyileştirme sağlayabilir, ancak dikkatli bir şekilde el ile ayarlama gerektirir.
Databricks, performans düşük olduğunda aralık birleştirmeleri için birleştirme ipuçlarının kullanılmasını önerir.
Aralık aralığı birleştirme noktası
Aralıkta birleştirme
-- using BETWEEN expressions
SELECT *
FROM points JOIN ranges ON points.p BETWEEN ranges.start and ranges.end;
-- using inequality expressions
SELECT *
FROM points JOIN ranges ON points.p >= ranges.start AND points.p < ranges.end;
-- with fixed length interval
SELECT *
FROM points JOIN ranges ON points.p >= ranges.start AND points.p < ranges.start + 100;
-- join two sets of point values within a fixed distance from each other
SELECT *
FROM points1 p1 JOIN points2 p2 ON p1.p >= p2.p - 10 AND p1.p <= p2.p + 10;
-- a range condition together with other join conditions
SELECT *
FROM points, ranges
WHERE points.symbol = ranges.symbol
AND points.p >= ranges.start
AND points.p < ranges.end;
Aralık çakışma aralığı birleştirme
Bir aralık çakışması aralığı birleştirme, koşulun her ilişkideki iki değer arasındaki aralıkların çakışmasını belirten önermeler içerdiği bir birleşimdir. Örneğin:
-- overlap of [r1.start, r1.end] with [r2.start, r2.end]
SELECT *
FROM r1 JOIN r2 ON r1.start < r2.end AND r2.start < r1.end;
-- overlap of fixed length intervals
SELECT *
FROM r1 JOIN r2 ON r1.start < r2.start + 100 AND r2.start < r1.start + 100;
-- a range condition together with other join conditions
SELECT *
FROM r1 JOIN r2 ON r1.symbol = r2.symbol
AND r1.start <= r2.end
AND r1.end >= r2.start;
Aralık birleştirme optimizasyonu
Aralık birleştirme iyileştirmesi, aşağıdaki birleşimler için gerçekleştirilir:
- Aralık veya aralık çakışma aralığı birleşiminde bir nokta olarak yorumlanabilecek bir duruma sahip olmak.
- Aralık birleştirme koşulunda yer alan tüm değerler sayısal türdedir (integral, kayan nokta, ondalık),
DATE
veyaTIMESTAMP
. - Aralık birleştirme koşulunda yer alan tüm değerler aynı türdedir. Ondalık türü söz konusu olduğunda, değerlerin de aynı ölçek ve duyarlıkta olması gerekir.
- Bir
INNER JOIN
veya aralık aralığındaki nokta birleşimi durumunda, sol tarafta nokta değeri olan birLEFT OUTER JOIN
veya sağ tarafta nokta değeri olan birRIGHT OUTER JOIN
. - Bölme boyutu ayarlama parametresine sahip olun.
Bölme boyutu
kutu boyutu, aralık koşulunun değer etki alanını eşit boyutta birden çok kutuya bölen sayısal bir ayar parametresidir. Örneğin, bölme boyutu 10 olan iyileştirme, etki alanını uzunluk 10 aralıkları olan bölmelere böler.
aralık koşulunda p BETWEEN start AND end
bir noktanız varsa ve 8 ve start
end
22 ise, bu değer aralığı 10 uzunluklu üç bölmeyle çakışıyor: 0'dan 10'a ilk bölme, 10'dan 20'ye ikinci bölme ve 20'den 30'a üçüncü bölme. Yalnızca aynı üç kategorideki noktalar bu aralıkta muhtemel birleştirme eşleşmeleri olarak değerlendirilmelidir. Örneğin, 32 isep
, 30 ile 40 arasında bir bölmeye düştüğünden, 8 start
ile 22 arasında end
bir düşüş olarak elenebilir.
Not
-
DATE
değerleri için, bölme boyutunun değeri gün olarak değerlendirilir. Örneğin, 7 bölme boyutu değeri bir haftayı temsil eder. -
TIMESTAMP
değerleri için, bölme boyutunun değeri saniye cinsinden değerlendirilmektedir. Alt saniye düzeyinde bir değer gerekiyorsa kesirli değerler kullanılabilir. Örneğin, 60 bölme boyutu değeri bir dakikayı, 0,1 bölme boyutu değeri ise 100 milisaniyeyi temsil eder.
Bölme boyutunu, sorguda bir aralık birleştirme önerisi kullanarak veya bir oturum yapılandırma parametresi ayarlayarak belirtebilirsiniz. Aralık birleştirme iyileştirmesi yalnızca bölme boyutunu, el ile belirtmeniz koşuluyla uygulanır. Bölüm Bölme boyutunu seçin, en uygun bölme boyutunun nasıl seçileceğini açıklar.
Aralık birleştirme ipucu kullanarak aralık birleştirmeyi etkinleştirin
SQL sorgusunda aralık birleştirme iyileştirmesini etkinleştirmek için, bölme boyutunu belirtmek için aralık birleştirme ipucu kullanabilirsiniz. İpucu, birleştirilmiş ilişkilerden birinin ilişki adını ve sayısal bölme boyutu parametresini içermelidir. İlişki adı bir tablo, görünüm veya alt sorgu olabilir.
SELECT /*+ RANGE_JOIN(points, 10) */ *
FROM points JOIN ranges ON points.p >= ranges.start AND points.p < ranges.end;
SELECT /*+ RANGE_JOIN(r1, 0.1) */ *
FROM (SELECT * FROM ranges WHERE ranges.amount < 100) r1, ranges r2
WHERE r1.start < r2.start + 100 AND r2.start < r1.start + 100;
SELECT /*+ RANGE_JOIN(c, 500) */ *
FROM a
JOIN b ON (a.b_key = b.id)
JOIN c ON (a.ts BETWEEN c.start_time AND c.end_time)
Not
Üçüncü örnekte ipucunu üzerine yerleştirmeniz c
.
Bunun nedeni birleşimlerin ilişkilendirici olarak bırakılmasıdır; bu nedenle sorgu (a JOIN b) JOIN c
olarak yorumlanır ve a
ipucu c
ile birleştirme değil b
ile a
birleşimi için geçerlidir.
#create minute table
minutes = spark.createDataFrame(
[(0, 60), (60, 120)],
"minute_start: int, minute_end: int"
)
#create events table
events = spark.createDataFrame(
[(12, 33), (0, 120), (33, 72), (65, 178)],
"event_start: int, event_end: int"
)
#Range_Join with "hint" on the from table
(events.hint("range_join", 60)
.join(minutes,
on=[events.event_start < minutes.minute_end,
minutes.minute_start < events.event_end])
.orderBy(events.event_start,
events.event_end,
minutes.minute_start)
.show()
)
#Range_Join with "hint" on the join table
(events.join(minutes.hint("range_join", 60),
on=[events.event_start < minutes.minute_end,
minutes.minute_start < events.event_end])
.orderBy(events.event_start,
events.event_end,
minutes.minute_start)
.show()
)
Ayrıca, birleştirilmiş DataFrame'lerden birine bir aralık birleştirme ipucu yerleştirebilirsiniz. Bu durumda, ipucu yalnızca sayısal bölme boyutu parametresini içerir.
val df1 = spark.table("ranges").as("left")
val df2 = spark.table("ranges").as("right")
val joined = df1.hint("range_join", 10)
.join(df2, $"left.type" === $"right.type" &&
$"left.end" > $"right.start" &&
$"left.start" < $"right.end")
val joined2 = df1
.join(df2.hint("range_join", 0.5), $"left.type" === $"right.type" &&
$"left.end" > $"right.start" &&
$"left.start" < $"right.end")
Oturum yapılandırmasını kullanarak aralık birleştirmeyi etkinleştirme
Sorguyu değiştirmek istemiyorsanız, bölme boyutunu yapılandırma parametresi olarak belirtebilirsiniz.
SET spark.databricks.optimizer.rangeJoin.binSize=5
Bu yapılandırma parametresi, aralık koşulu olan tüm birleşimler için geçerlidir. Ancak, aralık birleştirme ipucu aracılığıyla ayarlanan farklı bir bölme boyutu her zaman parametresi aracılığıyla ayarlananı geçersiz kılar.
Bölme boyutunu seçin
Aralık birleştirme optimizasyonunun etkinliği, uygun bölme boyutunun seçilmesine bağlıdır.
Küçük bir bölme boyutu, olası eşleşmelerin filtrelenmesine yardımcı olan daha fazla sayıda bölmeye neden olur.
Ancak, bölme boyutu karşılaşılan değer aralıklarından önemli ölçüde daha küçükse ve değer aralıkları birden çok bölme aralığıyla çakışıyorsa verimsiz hale gelir. Örneğin, p BETWEEN start AND end
koşuluna göre, start
1.000.000, end
1.999.999 ve bölme boyutu 10 olduğunda, değer aralığı 100.000 bölme ile çakışıyor.
Aralığın uzunluğu oldukça tekdüzense ve biliniyorsa, bölme boyutunu değer aralığının beklenen tipik uzunluğuna ayarlamanızı öneririz. Ancak, aralığın uzunluğu farklılık gösterir ve eğrilirse, kısa aralıkları verimli bir şekilde filtreleyen ve uzun aralıkların çok fazla bölmeyle çakışmasını önleyen bir bölme boyutu ayarlamak için bir bakiye bulunmalıdır. start
ve end
sütunları arasındaki aralıklarla ranges
bir tablo olduğunu varsayarsak, aşağıdaki sorguyla çarpık aralık uzunluğu değerinin farklı yüzdebirlik dilimlerini belirleyebilirsiniz:
SELECT APPROX_PERCENTILE(CAST(end - start AS DOUBLE), ARRAY(0.5, 0.9, 0.99, 0.999, 0.9999)) FROM ranges
Önerilen bölme boyutu ayarı, 90. yüzdebirlik dilimdeki değerin maksimum değeri veya 99. yüzdebirlik dilimdeki değerin 10'a bölünmesi veya 99,9. yüzdebirlik dilimdeki değerin 100'e bölünmesi vb. olabilir. Gerekçe şudur:
- 90. yüzdebirlik dilimdeki değer bölme boyutuysa, değer aralığı uzunluklarının yalnızca %10'u bölme aralığından daha uzundur, dolayısıyla 2'den fazla bitişik bölme aralığına yayılır.
- 99. yüzdebirlik dilimdeki değer bölme boyutuysa, değer aralığı uzunluklarının yalnızca %1'i 11'den fazla bitişik bölme aralığına yayılır.
- 99,9. yüzdebirlik dilimdeki değer bölme boyutuysa, değer aralığı uzunluklarının yalnızca %0,1'i 101'den fazla bitişik bölme aralığına yayılır.
- Aynı şey gerekirse 99,99., 99,999. yüzdelik dilimindeki değerler ve benzerleri için de yinelenebilir.
Açıklanan yöntem, birden çok bölme aralığıyla çakışan çarpık uzun değer aralıklarının miktarını sınırlar. Bu şekilde elde edilen bölme boyutu değeri, ince ayarlama için yalnızca bir başlangıç noktasıdır; gerçek sonuçlar belirli iş yüküne bağlı olabilir.