運行帶有限制運算子的 join 陳述句時,查詢結果集不正確。
子查詢之一:
SELECT A3.customerid FROM b1traderecords A3 WHERE A3.customerid < 100 limit 5
customerid
-----------
71
88
11
99
44
5 record(s) selected.
包含子查詢的 join 陳述句:
select A2.customerid from (SELECT A3.customerid FROM b1traderecords A3 WHERE A3.customerid < 100 limit 5) A0, (select customerid from b3customerinfo where customerrating > 0.7) A2 where A0.customerid = A2.customerid
customerid
-----------
88
44
88
9
90
5 record(s) selected.
回傳值“9”不在第一個子查詢結果中因此,連接結果集似乎不正確。
這是一個錯誤嗎?有什么建議?謝謝
uj5u.com熱心網友回復:
這是預期的行為。Redshift 是一個集群,其中不同的計算節點(和切片)獨立運行。不同的資料行分布在集群的“切片”周圍,因此每個都有不同的資料。當您在查詢上設定這樣的小限制時,首先到達的切片資料將通過限制,其余部分將丟失。因此,切片之間存在“競爭”以查看哪個首先回傳資料。誰“獲勝”可能會因各種原因而改變。
要從 LIMIT 查詢中獲得可預測的結果,您需要一個 ORDER BY 子句。
################### 更新
使用帶有 LIMIT(或 TOP)的子查詢中的 order 子句,結果變得可預測,但仍然存在一些問題。我重新創建了您的測驗用例并嘗試了這 3 個版本的查詢。
select A2.i1, a1.i1
from (select top 2 i1 from ffnr_i1 order by i1) A1
, (select i1 from ffnr_i2 ) A2
where A1.i1 = A2.i1 and A2.i1 > 20;
select A2.i1, a1.i1
from (select top 2 i1 from ffnr_i1 order by i1) A1
, (select i1 from ffnr_i2 ) A2
where A1.i1 = A2.i1;
select A2.i1, a1.i1
from (select top 2 i1 from ffnr_i1 order by i1) A1
, (select i1 from ffnr_i2 ) A2
where A2.i1 > 20;
以及對查詢運行 EXPLAIN。第一個只是將子查詢 where 子句移動到頂級 - 功能等效。解釋計劃顯示 i1 > 20 通過 a1.i1 = a2.i1 要求應用于第一個子查詢。它是在限制之后應用的,所以應該不會造成問題。
第二個示例產生預期結果 - 沒有匹配項。解釋計劃中唯一的變化是兩個表上不再有 > 20 where 子句。不出意外。
第三個示例也產生了您所期望的 - A2 與 A1 的前 2 個值的交叉連接。解釋計劃的唯一區別是這需要嵌套回圈連接,現在首先評估 A1。
因此,就像告訴它正在使用 LIMIT 排除匹配值、連接列上的 WHERE 原因以及另一個表上的隱含 WHERE 子句一樣。在這種情況下,查詢優化器似乎正在洗掉某些內容。您應該將此作為潛在問題/錯誤提交給 AWS。
我用現代連接語法重寫了查詢,看看這是否有助于優化器,但沒有運氣。我還向 A1 添加了更多值 (25, 26, 27 35, 36, 37),以防萬一在 LIMIT 之前應用 WHERE 條件,但這也沒有改變問題。
除非有人看到我遺漏的東西,否則我認為這可能是 Redshift 優化器錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/328333.html
