Created
October 1, 2012 16:06
-
-
Save miio/3812729 to your computer and use it in GitHub Desktop.
test run sql timing
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
module BulkCheck | |
class Storage | |
@@pool = [] | |
@@where_in = {} | |
@@cache = nil | |
def self.pool data | |
@@pool << data | |
end | |
def self.read | |
@@pool | |
end | |
def self.where symbol, val | |
if @@where_in[symbol].nil? | |
@@where_in[symbol] = [] | |
end | |
@@where_in[symbol] << val | |
p @@where_in | |
end | |
def self.obj | |
if Trigger.ready? | |
if @@cache.nil? | |
p "Example: run sql!" | |
@@cache = Mock.get_data | |
@@where_in = {} | |
end | |
return @@cache | |
else | |
Trigger.next | |
end | |
end | |
def self.last | |
@@pool.last | |
end | |
end | |
class Trigger | |
@@current=0 | |
def self.run | |
call_method Storage.read.first | |
end | |
def self.call_method obj | |
obj.bulk_check_unique | |
end | |
def self.ready? | |
return Storage.last == Storage.read[@@current] | |
end | |
def self.current | |
return @@current | |
end | |
def self.next | |
unless ready? | |
@@current+=1 | |
call_method Storage.read[@@current] | |
end | |
end | |
end | |
class Mock | |
def self.get_data | |
return [Test.new('a'),Test.new('b')] | |
end | |
end | |
end | |
class Test | |
def initialize val | |
@val = val | |
end | |
def bulk_check_unique | |
BulkCheck::Storage.where :name, @val | |
obj = BulkCheck::Storage.obj | |
unless obj.nil? | |
p obj | |
obj.each do |o| | |
p "#{o.to_s} is #{@val}" | |
p o.to_s == @val | |
end | |
end | |
end | |
def to_s | |
@val | |
end | |
end | |
names = ['a','b','c','d','e','f','g'] | |
target = [] | |
names.each do |obj| | |
BulkCheck::Storage.pool Test.new obj | |
end | |
# Start | |
BulkCheck::Trigger.run |
ベンチマークしてみた。
DBアクセス1回を0.1ミリ秒として(強引すぎるけど
user system total real
"Example: run sql!"
false
false
false
false
false
false
true
0.000000 0.000000 0.000000 ( 0.010812)
true
"Example: run sql!"
false
"Example: run sql!"
false
"Example: run sql!"
false
"Example: run sql!"
false
"Example: run sql!"
false
"Example: run sql!"
false
"Example: run sql!"
0.000000 0.000000 0.000000 ( 0.077724)
DBアクセスがボトルネックであればかなり回避できそう
問題点:異なるwhere_inを1つのメソッド内で同居できない。
回避としては、別メソッドにすればワンちゃんあるかも?
現状だと、Storageに入っている最終要素に達するまでひたすらバリデーションメソッドを叩いているため(最終要素に達した段階で一気に値を返す仕組み)
つまり、メソッドの途中から再実行できるわけもなくry
補足:異なるwhere_in というのは、一旦objメソッドでオブジェクトを取得できたけど、例えばその結果を用いて新たなobjメソッドを叩いても意味が無い状態
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
前置き
ActiveRecordのUniqueチェックの際、ご丁寧に要素1つ1つに対してバリデーションしてくれる(というか、バルクインサート使うにはgemを入れる必要がある)
あまりにも非効率なので(クエリ発行回数が無駄)、WHERE IN句を使って一度に取得したデータを元にチェックすればいいのではと思って書いてみたもの。
これはDB上のnameカラムに対してa,bというレコードが存在しているという前提で、'a','b','c','d','e','f','g'をインサートする際の事前チェックを行なってみた