conttagtable
(t) とcontfloattable
(cf)の 2 つのテーブルがあります。T には約 43k 行あります。CFは90億以上あります。
tagindex
両方のテーブルの列の両方のテーブルにインデックスを作成しました。この列は、 の一意の識別子および へのconttagtable
外部キーと考えることができます。このデータは、あたかもaであるかのように、両方のテーブルの列によって論理的に関連付けられていますが、もう一方のテーブルに PK または外部キーを明示的に作成しませんでした。データはマイクロソフトのアクセス ダンプから取得されたものであり、tagindex が一意であると信頼できるかどうかわからなかったため、「一意性」は強制されません。conttagtable
confloattable
tagindex
conttagtable.tagindex
PRIMARY KEY
contfloattable.tagindex
FOREIGN KEY (tagindex) REFERENCES conttagtable(tagindex)
データ自体は非常に大きいです。
contfloattable
各 の 15 分contfloattable.dateandtime
間隔ごとに、 から任意に選択された単一の行を取得する必要がありますconttagtable.tagid
。したがって、contfloattable
特定のtagid
に 30 分間にわたる 4000 個のサンプルがある場合、0 ~ 14 分の範囲のサンプルと 15 ~ 30 分の範囲のサンプルが必要です。15 分の範囲内の任意の 1 つのサンプルが許容されます。最初、最後、ランダム、何でも。
簡単に言えば、15 分ごとにサンプルを取得する必要がありますが、t.tagname ごとに 1 つのサンプルしか取得できません。現在、サンプルは 5 秒ごとに記録されており、データは 2 年間に及びます。これはビッグデータの問題であり、SQL に関しては私の頭をはるかに超えています。私がグーグルやSOで検索して試した時間間隔の解決策はすべて、実用的ではないほど長いクエリ時間を生み出しました。
- インデックスは高速結合に十分ですか? (時間間隔部分を省略した場合に表示されます)
- 他のインデックスを追加することでメリットがありますか?
- 上記の目標を達成するための最良/最速のクエリは何ですか?
スキーマといくつかのサンプル データを含む SQLFiddle を次に示します: http://sqlfiddle.com/#!1/c7d2f/2
スキーマ:
Table "public.conttagtable" (t)
Column | Type | Modifiers
-------------+---------+-----------
tagname | text |
tagindex | integer |
tagtype | integer |
tagdatatype | integer |
Indexes:
"tagindex" btree (tagindex)
Table "public.contfloattable" (CF)
Column | Type | Modifiers
-------------+-----------------------------+-----------
dateandtime | timestamp without time zone |
millitm | integer |
tagindex | integer |
Val | double precision |
status | text |
marker | text |
Indexes:
"tagindex_contfloat" btree (tagindex)
私が見たい出力は次のようなものです:
cf.dateandtime |cf."Val"|cf.status|t.tagname
--------------------------------------------------
2012-11-16 00:00:02 45 S SuperAlpha
2012-11-16 00:00:02 45 S SuperBeta
2012-11-16 00:00:02 45 S SuperGamma
2012-11-16 00:00:02 45 S SuperDelta
2012-11-16 00:15:02 45 S SuperAlpha
2012-11-16 00:15:02 45 S SuperBeta
2012-11-16 00:15:02 45 S SuperGamma
2012-11-16 00:15:02 45 S SuperDelta
2012-11-16 00:30:02 45 S SuperAlpha
2012-11-16 00:30:02 45 S SuperBeta
2012-11-16 00:30:02 45 S SuperGamma
2012-11-16 00:30:02 45 S SuperDelta
2012-11-16 00:45:02 42 S SuperAlpha
...などなど...
Clodoaldo が示唆しているように、これは私の最新の試みですが、スピードアップするための提案はありますか?
with i as (
select cf.tagindex, min(dateandtime) dateandtime
from contfloattable cf
group by
floor(extract(epoch from dateandtime) / 60 / 15),
cf.tagindex
)
select cf.dateandtime, cf."Val", cf.status, t.tagname
from
contfloattable cf
inner join
conttagtable t on cf.tagindex = t.tagindex
inner join
i on i.tagindex = cf.tagindex and i.dateandtime = cf.dateandtime
order by floor(extract(epoch from cf.dateandtime) / 60 / 15), cf.tagindex
上記のクエリプラン: http://explain.depesz.com/s/loR