sql >> データベース >  >> RDS >> PostgreSQL

15分ごとに1行の巨大な時系列テーブルを効率的にクエリする

    15分間隔:

    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 cf.dateandtime, t.tagname
    

    最適化を試みることができるように、このクエリの説明出力を表示します(機能する場合)。この回答に投稿できます。

    出力の説明

    "Sort  (cost=15102462177.06..15263487805.24 rows=64410251271 width=57)"
    "  Sort Key: cf.dateandtime, t.tagname"
    "  CTE i"
    "    ->  HashAggregate  (cost=49093252.56..49481978.32 rows=19436288 width=12)"
    "          ->  Seq Scan on contfloattable cf  (cost=0.00..38528881.68 rows=1408582784 width=12)"
    "  ->  Hash Join  (cost=270117658.06..1067549320.69 rows=64410251271 width=57)"
    "        Hash Cond: (cf.tagindex = t.tagindex)"
    "        ->  Merge Join  (cost=270117116.39..298434544.23 rows=1408582784 width=25)"
    "              Merge Cond: ((i.tagindex = cf.tagindex) AND (i.dateandtime = cf.dateandtime))"
    "              ->  Sort  (cost=2741707.02..2790297.74 rows=19436288 width=12)"
    "                    Sort Key: i.tagindex, i.dateandtime"
    "                    ->  CTE Scan on i  (cost=0.00..388725.76 rows=19436288 width=12)"
    "              ->  Materialize  (cost=267375409.37..274418323.29 rows=1408582784 width=21)"
    "                    ->  Sort  (cost=267375409.37..270896866.33 rows=1408582784 width=21)"
    "                          Sort Key: cf.tagindex, cf.dateandtime"
    "                          ->  Seq Scan on contfloattable cf  (cost=0.00..24443053.84 rows=1408582784 width=21)"
    "        ->  Hash  (cost=335.74..335.74 rows=16474 width=44)"
    "              ->  Seq Scan on conttagtable t  (cost=0.00..335.74 rows=16474 width=44)"
    

    このインデックスが必要なようです:

    create index cf_tag_datetime on contfloattable (tagindex, dateandtime)
    

    analyzeを実行します それを作成した後。ここで、大きなテーブルのインデックスは、変更のたびに更新する必要があるため、データの変更(挿入など)に大きなパフォーマンスの影響を与えることに注意してください。

    更新

    cf_tag_datetimeインデックス(tagindex、dateandtime)を追加しました。これが、新しい説明です:

    "Sort  (cost=15349296514.90..15512953953.25 rows=65462975340 width=57)"
    "  Sort Key: cf.dateandtime, t.tagname"
    "  CTE i"
    "    ->  HashAggregate  (cost=49093252.56..49490287.76 rows=19851760 width=12)"
    "          ->  Seq Scan on contfloattable cf  (cost=0.00..38528881.68 rows=1408582784 width=12)"
    "  ->  Hash Join  (cost=270179293.86..1078141313.22 rows=65462975340 width=57)"
    "        Hash Cond: (cf.tagindex = t.tagindex)"
    "        ->  Merge Join  (cost=270178752.20..298499296.08 rows=1408582784 width=25)"
    "              Merge Cond: ((i.tagindex = cf.tagindex) AND (i.dateandtime = cf.dateandtime))"
    "              ->  Sort  (cost=2803342.82..2852972.22 rows=19851760 width=12)"
    "                    Sort Key: i.tagindex, i.dateandtime"
    "                    ->  CTE Scan on i  (cost=0.00..397035.20 rows=19851760 width=12)"
    "              ->  Materialize  (cost=267375409.37..274418323.29 rows=1408582784 width=21)"
    "                    ->  Sort  (cost=267375409.37..270896866.33 rows=1408582784 width=21)"
    "                          Sort Key: cf.tagindex, cf.dateandtime"
    "                          ->  Seq Scan on contfloattable cf  (cost=0.00..24443053.84 rows=1408582784 width=21)"
    "        ->  Hash  (cost=335.74..335.74 rows=16474 width=44)"
    "              ->  Seq Scan on conttagtable t  (cost=0.00..335.74 rows=16474 width=44)"
    

    時間内に上がったようです:(ただし、order by句を削除すると(正確には必要なものではありませんが、機能します)、これが発生し、大幅に削減されます:

    "Hash Join  (cost=319669581.62..1127631600.98 rows=65462975340 width=57)"
    "  Hash Cond: (cf.tagindex = t.tagindex)"
    "  CTE i"
    "    ->  HashAggregate  (cost=49093252.56..49490287.76 rows=19851760 width=12)"
    "          ->  Seq Scan on contfloattable cf  (cost=0.00..38528881.68 rows=1408582784 width=12)"
    "  ->  Merge Join  (cost=270178752.20..298499296.08 rows=1408582784 width=25)"
    "        Merge Cond: ((i.tagindex = cf.tagindex) AND (i.dateandtime = cf.dateandtime))"
    "        ->  Sort  (cost=2803342.82..2852972.22 rows=19851760 width=12)"
    "              Sort Key: i.tagindex, i.dateandtime"
    "              ->  CTE Scan on i  (cost=0.00..397035.20 rows=19851760 width=12)"
    "        ->  Materialize  (cost=267375409.37..274418323.29 rows=1408582784 width=21)"
    "              ->  Sort  (cost=267375409.37..270896866.33 rows=1408582784 width=21)"
    "                    Sort Key: cf.tagindex, cf.dateandtime"
    "                    ->  Seq Scan on contfloattable cf  (cost=0.00..24443053.84 rows=1408582784 width=21)"
    "  ->  Hash  (cost=335.74..335.74 rows=16474 width=44)"
    "        ->  Seq Scan on conttagtable t  (cost=0.00..335.74 rows=16474 width=44)"
    

    私はまだこのインデックスを試していません...しかしそうします。スタンバイ。

    もう一度見てみると、転置インデックスはMerge Joinだけでなく使用できるので、さらに良いと思います。 最後のSortでも :

    create index cf_tag_datetime on contfloattable (dateandtime, tagindex)
    


    1. 既存の外部キーに固有の追加

    2. Mysqlのuniqueidentifierの代わりは何ですか

    3. Pythonサブプロセスからのmysqldump単一テーブル

    4. NHibernateおよびMonoでのOracleClientBlob 10Kの制限?