2011-05-17 27 views
2

我有一張數十億行的表格。 「錄製」字段上有每日分區,它是「沒有時區的時間戳」。我想知道哪些日子在桌子上。我知道我可以做這樣的事情:查看錶格時間戳字段中的唯一日期的最快方法?

SELECT recorded::date 
FROM table 
GROUP BY 1; 

在理想情況下應該可行,但在解釋上是相當高的,並指出這將需要一段時間的工作......如果這是我能做到的最好,我可以接受這一點(並且我們可以隨時關注這些數據),但是我想知道是否可以採用更有效的方式來實現這一點,因爲我每天都進行分區?

回答

2

您可以創建一個索引是這樣的:

create index your_index_name 
on table (date_trunc('day', recorded)) 

在我的測試,PostgreSQL的9.something使用順序掃描後簡單地索引「中記載的」列添加索引,按順序進行掃描前,和使用date_trunc()將其索引後進行索引掃描。選擇一天的行需要66ms沒有索引,68ms使用普通索引,13ms使用date_trunc()索引。

隨着數十億行,預計創建該索引需要幾分鐘。 (咳嗽)

1

有一個非常類似的線程在這裏:

Slow select distinct query on postgres

如果你知道最小/最大日期,你會比做一個序列掃描過更好的查詢對日期的列表整桌子。假設你看起來像這應該是快上記錄的索引,東西:

with days as (
select date_trunc('day', min(recorded))::date + k * interval '1 day' as day 
from records, 
    generate_series(0, 
        (select date_trunc('day', max(recorded))::date 
          - date_trunc('day', min(recorded)::date 
        from records 
    )) as k 
) 
select day 
from days 
where exists (
     select 1 
     from records 
     where day <= recorded and recorded < day + interval '1 day' 
    ); 

可能會有一些調整做上面的查詢,但總的想法是存在的:它會更快在索引字段上執行幾千個子查詢/索引掃描,而不是掃描幾十億行並聚合它們以便識別不同日子。

+0

如果表格每天使用一個分區進行分區,您甚至不需要日期索引,因爲約束排除將選擇正確的表格,並且從表格中讀取的第一行將滿足EXISTS。 – peufeu 2011-05-18 08:28:07

相關問題