Created
November 16, 2011 22:32
-
-
Save nettsundere/1371692 to your computer and use it in GitHub Desktop.
Тестирование скорости для http://habrahabr.ru/qa/13482/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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