|
1 | 1 | #!/usr/bin/env ruby |
| 2 | +require 'rubygems' |
| 3 | +require 'active_record' |
| 4 | + |
| 5 | +def bench |
| 6 | + start = Time.now |
| 7 | + yield |
| 8 | + finish = Time.now |
| 9 | + finish - start |
| 10 | +end |
| 11 | + |
| 12 | +def sql(query) |
| 13 | + ActiveRecord::Base.connection.execute(query) |
| 14 | +end |
2 | 15 |
|
3 | 16 | text_lines = File.read(File.join(File.dirname(__FILE__), '..', '..', 'data', 'romeo_and_juliet.txt')).split("\n") |
4 | 17 |
|
|
7 | 20 | data << {:line => line, :content => content} |
8 | 21 | end |
9 | 22 |
|
| 23 | +total_lines = data.size |
| 24 | + |
| 25 | +ActiveRecord::Base.establish_connection({ |
| 26 | + :database => 'knowsql_examples', :adapter => 'postgresql' |
| 27 | +}) |
| 28 | + |
| 29 | +sql %{ |
| 30 | + drop table if exists romeo_and_juliet_lines; |
| 31 | +
|
| 32 | + drop sequence romeo_and_juliet_lines_id_seq; |
| 33 | + create sequence romeo_and_juliet_lines_id_seq; |
| 34 | + |
| 35 | + create table romeo_and_juliet_lines ( |
| 36 | + id integer primary key default nextval('romeo_and_juliet_lines_id_seq'), |
| 37 | + line_no integer, |
| 38 | + contents varchar(256) |
| 39 | + ); |
| 40 | +} |
10 | 41 |
|
11 | | -def bench(query) |
12 | | - puts %{ |
13 | | - delete from benchmark; |
14 | | - insert into benchmark (stamp) values (NOW()); |
15 | | - #{query} |
16 | | - insert into benchmark (stamp) values (NOW()); |
17 | | - select (finish.stamp - start.stamp) as duration from |
18 | | - (select stamp from benchmark limit 1) as start, |
19 | | - (select stamp from benchmark limit 1 offset 1) as finish; |
20 | | - } |
| 42 | +class RomeoAndJulietLine < ActiveRecord::Base; end |
| 43 | + |
| 44 | +data.each do |row| |
| 45 | + sql %{insert into romeo_and_juliet_lines (line_no, contents) values ( |
| 46 | + #{row[:line]}, #{ActiveRecord::Base.connection.quote(row[:content])} |
| 47 | + );} |
21 | 48 | end |
22 | 49 |
|
23 | | -puts %{ |
24 | | - drop table if exists romeo_and_juliet; |
25 | | - drop table if exists benchmark; |
26 | | - create table romeo_and_juliet ( line_no integer, contents varchar(256) ); |
27 | | - create index line_no_idx on romeo_and_juliet(line_no); |
28 | | - create table benchmark ( stamp timestamp ); |
| 50 | +puts "Inserted #{RomeoAndJulietLine.count} lines of Romeo and Juliet" |
29 | 51 |
|
30 | | - insert into romeo_and_juliet (line_no, contents) values |
31 | | - #{data.collect{|row| "(#{row[:line]}, E'#{row[:content].gsub("'", "''")}')"}.join(",\n")} |
32 | | - ; |
| 52 | +puts "Performing 1000 finds without an index" |
| 53 | +without_index = bench do |
| 54 | + 1000.times do |
| 55 | + sql %{select * from romeo_and_juliet_lines where line_no = #{rand(total_lines)}} |
| 56 | + end |
| 57 | +end |
33 | 58 |
|
| 59 | +sql %{ |
| 60 | + create index romeo_and_juliet_lines_line_no_idx on romeo_and_juliet_lines(line_no); |
34 | 61 | } |
35 | | -bench(%{ |
36 | | - select * from romeo_and_juliet where line_no = 4001; |
37 | | - select * from romeo_and_juliet where line_no = 4101; |
38 | | - select * from romeo_and_juliet where line_no = 4201; |
39 | | - select * from romeo_and_juliet where line_no = 4301; |
40 | | - select * from romeo_and_juliet where line_no = 4401; |
41 | | - select * from romeo_and_juliet where line_no = 4501; |
42 | | - select * from romeo_and_juliet where line_no = 4601; |
43 | | - select * from romeo_and_juliet where line_no = 4701; |
44 | | - select * from romeo_and_juliet where line_no = 4801; |
45 | | - select * from romeo_and_juliet where line_no = 4901; |
46 | | -}) |
47 | | - |
48 | 62 |
|
| 63 | +puts "Performing 1000 find with an index" |
| 64 | +with_index = bench do |
| 65 | + 1000.times do |
| 66 | + sql %{select * from romeo_and_juliet_lines where line_no = #{rand(total_lines)}} |
| 67 | + end |
| 68 | +end |
49 | 69 |
|
| 70 | +puts %{ |
| 71 | +without index #{without_index} |
| 72 | +with index #{with_index} |
| 73 | +speedup #{((without_index / with_index) * 100).to_i} |
| 74 | +} |
50 | 75 |
|
0 commit comments