2015-09-16 80 views
0

sql查詢是相當標準的內部連接類型。 例如,比較n個表來查看所有n個表中存在哪個customerId將是基本的WHERE ... AND類型查詢。分區非常大的INNER JOIN SQL查詢

問題是表的大小是> 1000萬條記錄。數據庫是非規範化的。標準化不是一種選擇。 查詢要麼需要很長時間才能完成,要麼從未完成。

我不確定它是否相關,但我們使用spring xd作業模塊進行其他類型的查詢。

我不知道如何對這類作業進行分區,以便它可以並行運行,以便它花費更少的時間,因此如果某個步驟/子分區失敗,它可以從其停止的地方繼續。

其他類似問題的帖子建議使用數據庫引擎之外的替代方法,如在代碼中實現LOOP JOIN或使用MapReduce或Hadoop,從未使用過,或者我不確定是否值得查看此用例。

這種操作的標準方法是什麼,我希望它是相當普遍的。我可能會使用錯誤的搜索詞來研究方法,因爲我沒有遇到任何標準的解決方案或明確的方向。

的,而神祕的原始需求是:

三個非常大的表比較party_id列,以確定可用的客戶在三個表 即如果是與三大運營。 SAMPLE1.PARTY_ID AND SAMPLE2.PARTY_ID AND SAMPLE3.PARTY_ID

如果操作是OR,則選擇三個表中可用的所有客戶。 SAMPLE1.PARTY_ID或SAMPLE2.PARTY_ID或SAMPLE3.PARTY_ID

AND/OR在表格之間使用,然後根據需要進行比較。 SAMPLE1.PARTY_ID和SAMPLE2.PARTY_ID或SAMPLE3.PARTY_ID

我設置每個約4測試表與此定義

CREATE TABLE `TABLE1` (
    `CREATED` datetime DEFAULT NULL, 
    `PARTY_ID` varchar(45) NOT NULL, 
    `GROUP_ID` varchar(45) NOT NULL, 
    `SEQUENCE_ID` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`SEQUENCE_ID`) 
) ENGINE=InnoDB AUTO_INCREMENT=978536 DEFAULT CHARSET=latin1; 

然後在應該導致在一個範圍內添加1,000,000記錄時,每個只隨機數連接。

我用下面的測試查詢

SELECT `TABLE1`.`PARTY_ID` AS `pi1`, `TABLE2`.`PARTY_ID` AS `pi2`, `TABLE3`.`PARTY_ID` AS `pi3`, `TABLE4`.`PARTY_ID` AS `pi4` FROM `devt1`.`TABLE2` AS `TABLE2`, `devt1`.`TABLE1` AS `TABLE1`, `devt1`.`TABLE3` AS `TABLE3`, `devt1`.`TABLE4` AS `TABLE4` WHERE `TABLE2`.`PARTY_ID` = `TABLE1`.`PARTY_ID` AND `TABLE3`.`PARTY_ID` = `TABLE2`.`PARTY_ID` AND `TABLE4`.`PARTY_ID` = `TABLE3`.`PARTY_ID` 

它應該完成在10分鐘和表大小的10倍。 我的測試查詢還沒有完成,它已經運行了15分鐘

+1

「比較n個表以查看所有n個表中存在哪個customerId」對我來說聽起來不像是「相當標準的內部連接類型」。如果您發佈了您正在嘗試執行的示例查詢,這可能會有所幫助。 – Uueerdo

+0

當然,做你自己的分區是一件麻煩事。如果你足夠頻繁地處理這個級別的處理,你是否願意轉向大數據環境?如果是這樣,我建議http://trustedanalytics.github.io - 我知道它可以處理您嘗試執行的加入級別。 – Prune

+0

@Uueerdo我添加了需求的描述。這是我最初的猜測,這將是一個內部聯接。但顯然使用sql並不是最好的解決方案,因爲它需要很長時間。我在想數據科學中可能存在一些替代算法或者其他什麼 – justify

回答

0

以下可以執行比現有的基於連接的查詢更好:

select party_id from 
(select distinct party_id from SAMPLE1 union all 
select distinct party_id from SAMPLE2 union all 
select distinct party_id from SAMPLE3) as ilv 
group by party_id 
having count(*) = 3 

修改count(*)條件匹配被查詢的表的數量。

如果你想返回party_id值存在於任何表,而不是全部,那麼忽略最後的having條款。

+0

在「任何表格」場景中,all all的'all'部分也可以省略。 – Uueerdo

+0

如果UNION將一個表中的行結果與另一個表的行(垂直)組合起來,那麼您能解釋一下這個查詢如何排除在SAMPLE2中不存在的任何party_id,例如? – justify

+0

@justify:這就是'有count(*)= 3'子句所做的 - 不在所有3個表中的任何'party_id'值都會少於3個。 (這就是爲什麼必須修改計數條件以匹配查詢中的表總數。) –