Skip to content

Instantly share code, notes, and snippets.

@sonalkr132
Last active March 19, 2019 07:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sonalkr132/2070908d1d036e9916ca1002fa13b6c0 to your computer and use it in GitHub Desktop.
Save sonalkr132/2070908d1d036e9916ca1002fa13b6c0 to your computer and use it in GitHub Desktop.
All benchmarks were done locally.
# old
$ time curl http://localhost:3000/api/v1/activity/latest.json
real 0m1.220s
user 0m0.020s
sys 0m0.008s
# new
$ time curl http://localhost:3000/api/v1/activity/latest.json
real 0m0.233s
user 0m0.021s
sys 0m0.017s
/*old*/
# explain analyze SELECT "versions".* FROM "versions" WHERE (
versions.id IN (
SELECT max(versions.id) FROM versions GROUP BY versions.rubygem_id
HAVING COUNT(versions.rubygem_id) = 1))
ORDER BY "versions"."created_at" DESC LIMIT 50;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=88948.21..88948.33 rows=50 width=390) (actual time=1332.360..1332.372 rows=50 loops=1)
-> Sort (cost=88948.21..90244.03 rows=518330 width=390) (actual time=1332.359..1332.369 rows=50 loops=1)
Sort Key: versions.created_at DESC
Sort Method: top-N heapsort Memory: 53kB
-> Nested Loop (cost=70061.58..71729.66 rows=518330 width=390) (actual time=711.342..1298.906 rows=47959 loops=1)
-> HashAggregate (cost=70061.16..70063.16 rows=200 width=4) (actual time=710.975..728.621 rows=47959 loops=1)
Group Key: max(versions_1.id)
-> HashAggregate (cost=68872.53..69466.85 rows=47545 width=8) (actual time=651.321..697.349 rows=47959 loops=1)
Group Key: versions_1.rubygem_id
Filter: (count(versions_1.rubygem_id) = 1)
Rows Removed by Filter: 110345
-> Seq Scan on versions versions_1 (cost=0.00..61097.59 rows=1036659 width=8) (actual time=0.167..266.154 rows=1029670 loops=1)
-> Index Scan using versions_pkey on versions (cost=0.42..8.32 rows=1 width=390) (actual time=0.011..0.011 rows=1 loops=47959)
Index Cond: (id = (max(versions_1.id)))
Planning time: 2.811 ms
Execution time: 1334.424 ms
(16 rows)
/*new*/
# explain analyze SELECT "versions".* FROM "versions" WHERE ( versions.rubygem_id IN ( SELECT versions.rubygem_id FROM versions
GROUP BY versions.rubygem_id HAVING COUNT(versions.rubygem_id) = 1
ORDER BY versions.rubygem_id DESC LIMIT 50)) ORDER BY "versions"."created_at" DESC;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort (cost=4827.87..4830.60 rows=1090 width=390) (actual time=0.753..0.765 rows=50 loops=1)
Sort Key: versions.created_at DESC
Sort Method: quicksort Memory: 53kB
-> Nested Loop (cost=0.85..4772.88 rows=1090 width=390) (actual time=0.057..0.632 rows=50 loops=1)
-> Limit (cost=0.42..244.93 rows=50 width=4) (actual time=0.040..0.300 rows=50 loops=1)
-> GroupAggregate (cost=0.42..232500.36 rows=47545 width=4) (actual time=0.038..0.286 rows=50 loops=1)
Group Key: versions_1.rubygem_id
Filter: (count(versions_1.rubygem_id) = 1)
Rows Removed by Filter: 14
-> Index Only Scan Backward using index_versions_on_rubygem_id on versions versions_1 (cost=0.42..226722.76 rows=1036659 width=4) (actual time=0.026..0.194 rows=112 loops=1)
Heap Fetches: 112
-> Index Scan using index_versions_on_rubygem_id on versions (cost=0.42..90.33 rows=22 width=390) (actual time=0.004..0.005 rows=1 loops=50)
Index Cond: (rubygem_id = versions_1.rubygem_id)
Planning time: 0.685 ms
Execution time: 0.885 ms
# def self.new_pushed_versions(limit = 5)
# subquery = <<-SQL
# versions.id IN (SELECT max(versions.id)
# FROM versions
# GROUP BY versions.rubygem_id
# HAVING COUNT(versions.rubygem_id) = 1)
# SQL
# Version.where(subquery).by_created_at.limit limit
# end
# def self.newer_pushed_versions(limit = 5)
# subquery = <<-SQL
# versions.rubygem_id IN ( SELECT versions.rubygem_id FROM versions
# GROUP BY versions.rubygem_id HAVING COUNT(versions.rubygem_id) = 1
# ORDER BY versions.rubygem_id DESC LIMIT #{limit})
# SQL
# versions = Version.where(subquery)
# end
require 'benchmark/ips'
Benchmark.ips do |x|
x.report("newer_pushed_versions") do
Version.newer_pushed_versions(50)
end
x.report("new_pushed_versions") do
Version.new_pushed_versions(50)
end
x.compare!
end
Warming up --------------------------------------
newer_pushed_versions
9.467k i/100ms
new_pushed_versions 2.841k i/100ms
Calculating -------------------------------------
newer_pushed_versions
100.529k (_ 1.6%) i/s - 511.218k in 5.086640s
new_pushed_versions 29.180k (_ 1.4%) i/s - 147.732k in 5.063841s
Comparison:
newer_pushed_versions: 100529.1 i/s
new_pushed_versions: 29179.7 i/s - 3.45x slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment