Skip to content

Instantly share code, notes, and snippets.

@nettsundere
Created November 16, 2011 22:32
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 nettsundere/1371692 to your computer and use it in GitHub Desktop.
Save nettsundere/1371692 to your computer and use it in GitHub Desktop.
Тестирование скорости для http://habrahabr.ru/qa/13482/
# Encoding: UTF-8
require 'mysql'
# Запросы
class Queries
attr_reader :results
CREATE_SQL = 'CREATE TABLE test (id INT NOT NULL AUTO_INCREMENT, field VARCHAR(20), PRIMARY KEY (id)) ENGINE=INNODB'
DROP_SQL = 'DROP TABLE test'
# Инициализация.
# Получает объект для работы с mysql и необходимое количество элементов в таблице.
def initialize(mysql_connection, items_in_db)
@m = mysql_connection
@items_in_db = items_in_db
perform_sql
end
private
def perform_sql
@m.query CREATE_SQL
begin
seed
@results = {:old => query_old, :new => query_new, :new_cached => query_cached}
ensure
@m.query DROP_SQL
end
end
def seed
@val_str ||= ("('some_val')," * @items_in_db)[0..-2]
@m.query("INSERT INTO test (field) VALUES #{@val_str}")
end
def timered_query(repeats = 80000)
s_time = current_time
repeats.times { yield }
(current_time - s_time) / repeats.to_f
end
# Старый стиль.
def query_old
timered_query { @m.query("SELECT id FROM test ORDER BY RAND() LIMIT 1").fetch_row[0] }
end
# Новый стиль.
def query_new
timered_query do
max = get_max
@m.query("SELECT id FROM test WHERE id >= #{rand(1..max)} LIMIT 1").fetch_row[0]
end
end
# Стиль с кэшированием (тут max сохраняется в памяти).
# Например, можно сохранять max в ключе memcached или redis
# и обновлять при:
# [1] Добавлении записи
# [2] Удалении записи
# Можно даже сохранить max в cпециальной таблице, если нет возможности использовать key-value
# хранилище. Получаем в любом случае солидный выигрыш.
def query_cached
timered_query do
@max_cached ||= get_max
@m.query("SELECT id FROM test WHERE id >= #{rand(1..@max_cached)} LIMIT 1").fetch_row[0]
end
end
def get_max
@m.query("SELECT MAX(id) FROM test").fetch_row[0].to_i
end
def current_time
Time.now.to_i
end
end
puts "Введите пароль, пожалуйста:"
system "stty -echo" # Прячем ввод
password = gets[0..-2]
system "stty echo" # Снова показываем ввод
puts "Благодарю вас!"
con = Mysql.new('localhost', 'root', password, 'TEST')
begin
[10, 100, 1000, 10000].each do |items_count|
results = Queries.new(con, items_count).results
puts "Для #{items_count} элементов результаты показаны следующие:"
puts "Было: #{results[:old]} сек. в среднем"
puts "Стало: #{results[:new]} сек. в среднем"
puts "Стало (если бы max сохранили в redis или memcached): #{results[:new_cached]} сек. в среднем"
end
ensure
con.close
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment