タイトルの通りpostgresからデータを取得する時間を短縮したいです。
以前にも質問させていただいたのですが、前回とは少し内容が変わっております。
テーブルには2700万件ほどデータが格納されております。
日付の範囲を指定して取得していたデータの中から100件以下のデータを取得して画面に表示させるということをやっております。
以前は指定された範囲内のデータを全て取得してプログラム内で間引いていたのですが、SQL内で間引くようにしました。
プログラム内で間引いていた時よりだいぶ速度は改善されたのですが、検索範囲を1年で検索した際は7秒近くかかっている状況になります。
それを3秒以内に抑えたいです。
vacuum、reindexは行っております。
テーブルの分割については色々事情があってなるべくしたくない方法です。
DBの設定、OS、ハードなどについては、すでに動いているシステムなので変更することが出来ない状況です。
なるべくSQLの見直し、テーブルの設計だけで速度を改善させたいです。
postgresのバージョンは9.5になります。
以下にテーブルの構成、SQL文、実行計画を載せます。
申し訳ございませんがどなたかアドバイスを頂ければと思います。
注)テーブルにrow_numの項目を追加してサブクエリを実行しないSQLでも行ったのですが、あまり変化はありませんでした。
※テーブル構成 テーブル名=「details_table」
response_time timestamp
AA_id varchar
port varchar
octets numeric
※SQL
SELECT
response_time
, octets_diff
FROM
(
SELECT
total.response_time
, total.octets
, row_number() over (ORDER BY response_time DESC) AS no
FROM
details_table total
WHERE
AA_id = '0000-0000-0000-0840'
AND port = '2110'
AND response_time BETWEEN '2006/10/20 11:27:05' AND '2008/10/20 11:27:05'
) AS totaltable
WHERE
mod(no, 960) = 1 ←検索範囲によって960という値を変化させてデータを100件以下取得する
ORDER BY
totaltable.response_time DESC
, no DESC
※実行計画
Sort (cost=193984.85..193984.90 rows=22 width=24) Sort Key: totaltable.response_time, totaltable.no
+-Subquery Scan on totaltable (cost=193844.45..193984.36 rows=22 width=24) Filter: (mod(totaltable.no, 960::bigint) = 1)
+-WindowAgg (cost=193844.45..193919.78 rows=4305 width=16)
+-Sort (cost=193844.45..193855.21 rows=4305 width=16) Sort Key: total.response_time
+-Seq Scan on details_table total (cost=0.00..193584.60 rows=4305 width=16) Filter: ((response_time >= '2006-10-20 11:27:05+09'::timestamp with time zone) AND (response_time <= '2008-10-20 11:27:05+09'::timestamp with time zone) AND ((AA_id)::text = '0000-0000-0000-0840'::text) AND ((port)::text = '2110'::text))
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/10/24 00:30
2016/10/24 02:05 編集
2016/10/24 02:59
2016/10/24 03:07
2016/10/26 02:06