I have a token_count table.
docid | tokenid | tf | log_ave_tf
1 | 1 | 1 | null
1 | 2 | 2 | null
2 | 1 | 3 | null
2 | 2 | 1 | null
ALTER TABLE token_count
ADD COLUMN log_ave_tf real;
I am trying to calculate the values for the log_ave_tf column and the formula is as follows:
log_ave_tf = (1 + log(tf)) / (1 + log(average tf for document))
Here's the code I'm running:
UPDATE token_count tc
SET log_ave_tf = (1 + log(2, tf)) / (1+log(2, subquery.avg_tf))
FROM (
SELECT docid, avg(tf) as avg_tf
FROM token_count
GROUP BY docid
) subquery
WHERE subquery.docid = tc.docid;
Took it 1 and a half minutes on a 1000 document dataset, tried running it on a 100 000 document dataset(36 million rows in token_count) and had to cancel the query after 5 hours. And I need it to work on a 4 million document dataset. Is there a way to optimize this query so it doesn't take so much time?
explain (analyze, buffers, format text) for a dataset of 1000 documents:
"Update on token_count tc (cost=37563.77..92185.42 rows=1128913 width=94) (actual time=89287.844..89287.847 rows=0 loops=1)"
" Buffers: shared hit=2319962 read=13056 dirtied=17040 written=922"
" -> Hash Join (cost=37563.77..92185.42 rows=1128913 width=94) (actual time=768.179..83652.020 rows=1128913 loops=1)"
" Hash Cond: (tc.docid = subquery.docid)"
" Buffers: shared hit=32402 read=8796 dirtied=1 written=922"
" -> Seq Scan on token_count tc (cost=0.00..31888.13 rows=1128913 width=30) (actual time=0.089..702.652 rows=1128913 loops=1)"
" Buffers: shared hit=16206 read=4393 written=922"
" -> Hash (cost=37552.67..37552.67 rows=888 width=96) (actual time=767.982..767.983 rows=1001 loops=1)"
" Buckets: 1024 Batches: 1 Memory Usage: 93kB"
" Buffers: shared hit=16196 read=4403 dirtied=1"
" -> Subquery Scan on subquery (cost=37532.69..37552.67 rows=888 width=96) (actual time=766.111..767.517 rows=1001 loops=1)"
" Buffers: shared hit=16196 read=4403 dirtied=1"
" -> HashAggregate (cost=37532.69..37543.79 rows=888 width=36) (actual time=766.105..767.119 rows=1001 loops=1)"
" Group Key: token_count.docid"
" Batches: 1 Memory Usage: 321kB"
" Buffers: shared hit=16196 read=4403 dirtied=1"
" -> Seq Scan on token_count (cost=0.00..31888.13 rows=1128913 width=8) (actual time=0.010..231.895 rows=1128913 loops=1)"
" Buffers: shared hit=16196 read=4403 dirtied=1"
"Planning Time: 0.222 ms"
"Execution Time: 89288.014 ms"