2017-05-10 59 views
0

在我的Crate.io數據庫中,我有一個表,當前有50萬行,大小爲16GB。 如果我試圖讓每一天條目的數量與下面的語句一切工作正常(除了性能,但是這不應該是此刻的問題):不同的問題?

SELECT 
date_format('%Y-%m-%d', date_trunc('day', "days")) AS "Day", 
count(*) AS "Count" 
FROM "doc"."mytable" 
WHERE 
    date_format('%Y-%m-%d', date_trunc('day', "days")) BETWEEN date_format('%Y-%m-%d', date_trunc('day', current_timestamp + -2592000000)) 
    AND date_format('%Y-%m-%d', date_trunc('day', current_timestamp + -86400000)) 
GROUP BY date_format('%Y-%m-%d', date_trunc('day', "days")) 
ORDER BY date_format('%Y-%m-%d', date_trunc('day', "days")) ASC limit 100; 

但如果我嘗試做一個在像這樣的另一個列中不同:

SELECT 
date_format('%Y-%m-%d', date_trunc('day', "days")) AS "Day", 
count(DISTINCT customerid) AS "Count" 
FROM "doc"."mytable" 
WHERE 
    date_format('%Y-%m-%d', date_trunc('day', "days")) BETWEEN date_format('%Y-%m-%d', date_trunc('day', current_timestamp + -2592000000)) 
    AND date_format('%Y-%m-%d', date_trunc('day', current_timestamp + -86400000)) 
GROUP BY date_format('%Y-%m-%d', date_trunc('day', "days")) 
ORDER BY date_format('%Y-%m-%d', date_trunc('day', "days")) ASC limit 100; 

該語句將失敗,

SQLActionException [CircuitBreakingException:[查詢]數據太大時,數據[收集:0]將是較大的第的極限[1267571097/1.1GB]

大家有一個想法,爲什麼一個COUNT(DISTINCT列)有太多的數據有問題,而是一個COUNT(*)不?我該如何解決這個問題?

回答

0

count是一個非常輕量級的操作,因爲只需要一個數字(長整數),每一行都會遞增。而對於不同的計數,所有的值都必須保存在內存中才能確定一個值是否已經存在(沒有增量)或者是否是新的(增量計數器)。

爲了解決CircuitBreakingException(這可以避免陷入困境的節點,否則會拋出OutOfMemory並且節點將無法使用),請增加包裝箱進程的HEAP。 如何設置HEAP大小取決於使用的分佈,通常可以使用CRATE_HEAP_SIZE環境變量。

增加HEAP也可以爲您的第一組提供更好的查詢性能。一個很好的規則是給出包裝箱50%的可用內存,所以另外50%可以被操作系統文件系統緩存使用(該包裝箱也受益)。

+0

感謝您的回答。我明白,更多的內存會提高性能,但真正的問題是:如果我有大約3TB的數據(我們爲此表計劃的真實數據量是多少),我需要多少內存? 目前我在小型系統上只用16GB進行測試。現在所有的測試都顯示出來,我們不需要太多的內存來存儲數據,但是用於查詢數據的內存很多。但是這也比ES/Kibana所需的要少得多。這是我們想要使用Crate的原因之一。但是現在我不確定這個決定:l。 – Ragin

+0

如果用於不同計數的列類型是固定大小類型,例如很長時間以來,您可以通過此類型所需的字節數來增加不同值的數量(例如,請參閱https://github.com/crate/crate/blob/master/core/src/main/java/io/crate/types /LongType.java#L150)。這會給你一個粗略的估計。如果它是一個字符串類型,那麼估計字符串所需的字節取決於字符串值的長度將更加困難。 –