s2jdbcで、JOIN数が多い場合の注意について。
プロジェクトも中盤、さあslow-query-logを元にSQLのパフォーマンスチューニングするか、という時、困った事が・・
public class Test1Service extends AbstractService<Test1> { public List<Test1> find(Integer param1) { return select().leftOuterJoin(Test1Names.test2()).leftOuterJoin(Test1Names.test3()) .where(new SimpleWhereEx().eq(Test1Names.CTinyint(), param1)).getResultList(); } }
test1を親に、test2、test3を外部結合しています。さて、どのようにクエリが発行されたでしょうか。
select T1_.C_TINYINT as C1_, T1_.C_SMALLINT as C2_, T1_.C_INT as C3_, T1_.C_MEDIUMINT as C4_, T1_.C_BIGINT as C5_, T1_.C_BOOLEAN as C6_, T1_.C_FLOAT as C7_, T1_.C_DOUBLE as C8_, T1_.C_DECIMAL as C9_, T1_.C_DATE as C10_, T1_.C_DATETIME as C11_, T1_.C_TIMESTAMP as C12_, T1_.C_TIME as C13_, T1_.C_YEAR as C14_, T1_.C_CHAR as C15_, T1_.C_VARCHAR as C16_, T1_.C_TINYTEXT as C17_, T1_.C_TEXT as C18_, T1_.C_MEDIUMTEXT as C19_, T1_.C_LONGTEXT as C20_, T1_.C_TINYBLOB as C21_, T1_.C_BLOB as C22_, T1_.C_MEDIUMBLOB as C23_, T1_.C_LONGBLOB as C24_, T1_.C_ENUM as C25_, T1_.C_SET as C26_, T2_.C_TINYINT as C27_, T2_.C_SMALLINT as C28_, T2_.C_INT as C29_, T2_.C_MEDIUMINT as C30_, T2_.C_BIGINT as C31_, T2_.C_BOOLEAN as C32_, T2_.C_FLOAT as C33_, T2_.C_DOUBLE as C34_, T2_.C_DECIMAL as C35_, T2_.C_DATE as C36_, T2_.C_DATETIME as C37_, T2_.C_TIMESTAMP as C38_, T2_.C_TIME as C39_, T2_.C_YEAR as C40_, T2_.C_CHAR as C41_, T2_.C_VARCHAR as C42_, T2_.C_TINYTEXT as C43_, T2_.C_TEXT as C44_, T2_.C_MEDIUMTEXT as C45_, T2_.C_LONGTEXT as C46_, T2_.C_TINYBLOB as C47_, T2_.C_BLOB as C48_, T2_.C_MEDIUMBLOB as C49_, T2_.C_LONGBLOB as C50_, T2_.C_ENUM as C51_, T2_.C_SET as C52_, T3_.C_TINYINT as C53_, T3_.C_SMALLINT as C54_, T3_.C_INT as C55_, T3_.C_MEDIUMINT as C56_, T3_.C_BIGINT as C57_, T3_.C_BOOLEAN as C58_, T3_.C_FLOAT as C59_, T3_.C_DOUBLE as C60_, T3_.C_DECIMAL as C61_, T3_.C_DATE as C62_, T3_.C_DATETIME as C63_, T3_.C_TIMESTAMP as C64_, T3_.C_TIME as C65_, T3_.C_YEAR as C66_, T3_.C_CHAR as C67_, T3_.C_VARCHAR as C68_, T3_.C_TINYTEXT as C69_, T3_.C_TEXT as C70_, T3_.C_MEDIUMTEXT as C71_, T3_.C_LONGTEXT as C72_, T3_.C_TINYBLOB as C73_, T3_.C_BLOB as C74_, T3_.C_MEDIUMBLOB as C75_, T3_.C_LONGBLOB as C76_, T3_.C_ENUM as C77_, T3_.C_SET as C78_ from TEST1 T1_ left outer join TEST2 T2_ on T2_.c_tinyint = T1_.c_tinyint left outer join TEST3 T3_ on T3_.c_tinyint = T1_.c_tinyint where (T1_.C_TINYINT = 1)
おおお・・・
JOINしたテーブルも含めた全テーブルの全カラムselectしてる・・・
実はこのs2jdbcですが、現状正規のやり方でselectするカラムを選択できません。
このサンプルではJOIN数は2テーブルだけですが、5〜10テーブルJOINしたらどうなるでしょう。
SQL自体は一瞬で結果が返ります。
しかし、問題はそこではなかった・・・・
SQLの結果セットをEntityのListにマッピングする処理が遅い!!
よくあるのが「なんかこのservice遅いよ?」とDBAに相談が行くが、serviceで実行するのではなく、mysqlclientでSQLを直に叩くと速い。
結局entityへのマッピングが遅いのでした。
この件を踏まえると、
JOIN数が多いか、多くなりそうな場合は最初からSQLファイルに手でSQLを書いた方がいい
ということになりますね。
もし前トピックのs2jdbcのSimpleWhereをカスタマイズするの
whereが全削除されて全件selectされたら・・・・どうなるか解りますよね。

- 作者: Baron Schwartz,Peter Zaitsev,Vadim Tkachenko,Jeremy D. Zawodny,Arjen Lentz,Derek J. Balling,伊藤直也(監訳),田中慎司(監訳),吉川英興(監訳),株式会社クイープ
- 出版社/メーカー: オライリージャパン
- 発売日: 2009/12/14
- メディア: 大型本
- 購入: 17人 クリック: 354回
- この商品を含むブログ (46件) を見る