誰か、ココが嫌だよQuery Builder的なエントリを書いてくれないかな。
使いどころ
- 動的に条件を組み立てるところ(whereに与えるカラムが変わったりする)
使わなかったら、複雑な条件を動的に組み立てる場合は、sprintfでSQLを組み立てるみたいなことになって、それは劣化Query Builderを自作しているのと変わらないんじゃないですかね。
生のSQLも別に嫌いじゃないし、普通に書いてるけど、コードにはあんまり書かないです。
Query Builder のパフォーマンス
パフォーマンスについては、クエリを数個作る程度のことが多少遅くても、ボトルネックにはならない。
1/7500秒で処理できていたのが、1/2500秒かかるようになったとしても、困る人はあんまりいない。
Query Builder は余計なことするからなー
しません。
DBIx::Class はリレーションを設定していると、while で回して、foreign key で数珠つなぎにやってたら、千回くらいクエリ投げちゃった♪
みたいなことはあり得るかも知れませんけど。SQL::Abstract自体は、SQLを組み立てるだけです。
それは、Query Builderの問題ではなくて、ORマッパーの問題です。
SQL::Abstract::Moreは普通にSQL書くのとあまり変わらない
join はちょっと微妙なところはありますが。また、where 部分とかはどっかで組み立てた結果をそこに当てることになること場合は、ぱっと見分かりませんけどね。where の順番とかはハッシュで渡すと変わってしまいますが、配列リファレンスで一つずつ条件を渡せば、順番通りになります。
my ($s, @binds) = $sql->select # select ( '-columns' => [ # x.id, y.id, count(*) as cnt 'x.id', 'y.id', 'count(*) as cnt', ], '-from' => [ # from '-join', 'table1|x', # table1 as x 'x.id=y.table1_id,x.col1=y.col1',# on x.id = y.table1_id and x.col1 = y.col1 <- ここだけ、順番が違う 'table2|y' # inner join table2 as y ], '-where' => { # where 'x.type' => '1', # x.type = 1 and date = '2011-12-05' and y.name = 'name' 'date' => '2011-12-05', 'y.name' => 'name' }, '-group_by' => [ # group by (x.id, y.id) 'x.id', 'y.id' ], '-limit' => 3 # limit 3 );
運用者の立場
というわけでもないけど、DBIx::QueryLogで吐き出されるSQLを見て、index使われてないからこのカラムもwhereに入れてとか、それパーティショニング使われてないから、このカラムは必ず入れてみたいなのは、Query Builder に何を使おうが別に問題なくできる。
デバッグでも、基本的にQueryLogを見て、組み立て部分間違ってないかなぁというのをチェックするとかが多い。
本番にいきなり投入されて、なんか遅くなっちゃったんだけど…とかだったらご残念としか言いようがないけど。
まぁ、この辺は、Query Builderと関係ないレイヤーの話なんじゃないかと思ったりします。
※その話でいうと、SQL::Abstract::Moreで吐き出すSQLが整形されていないのがみにくいのは結構見づらいので、整形するコードでも書こうかなぁと思ったり、思わなかったりする。