Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

SlowQueryとの戦い

2,991 views

Published on

2014/10/11 PHPカンファレンス2014 LT無差別級での発表資料
遭遇した衝撃的なSQLを紹介し、ORMと開発者に一言申します。

Published in: Engineering

SlowQueryとの戦い

  1. 1. SlowQueryとの戦い (ほとんどORM) 2014/10/11 PHP Conference 2014 株式会社サイバード ゲーム事業本部 後藤 健
  2. 2. 後藤 健 • 新卒2年目 25歳 • ゲームインフラチーム • インフラ、ミドルウェアまわり • PHPer(たまにPython) • 趣味 車・ライブ・スノーボード etc.. • Twitter : @gotyoooo
  3. 3. さっそくですが。
  4. 4. O/Rマッパー 使ってる人! 挙手!!!
  5. 5. ありがとうございます!
  6. 6. O/Rマッパー なんて使わねー 俺は生SQLだ!! 挙手!!!
  7. 7. ありがとうございます!
  8. 8. 世の中的なO/Rマッパー 利用率が分かったところで
  9. 9. http://blog-imgs-54-origin.fc2.com/j/i/k/jikomanzoku009/saa.jpg
  10. 10. SQLにはご注意を http://www.weblio.jp/img/dict/hyazi/112.gif
  11. 11. 特にO/Rマッパー をご利用の皆様 http://www.weblio.jp/img/dict/hyazi/112.gif
  12. 12. http://cyline-jp.com/download/SQL.png http://f.st-hatena.com/images/fotolife/G/GET/20080131/20080131075901.jpg
  13. 13. じゃないと http://cyline-jp.com/download/SQL.png http://f.st-hatena.com/images/fotolife/G/GET/20080131/20080131075901.jpg
  14. 14. 恐ろしいこと になりますよ
  15. 15. では実例
  16. 16. その1
  17. 17. 意味のないソート
  18. 18. SELECT * FROM t1 WHERE ~省略~ ORDER BY t1.updated DESC, t1.updated ASC LIMIT 1
  19. 19. SELECT * FROM t1 WHERE ~省略~ ORDER BY t1.updated DESC, t1.updated ASC LIMIT 1
  20. 20. http://www.rosei.jp/jinjour/wp-content/uploads/2011/12/fotolia_36435421_Subscription_L.jpg
  21. 21. Model_Collection::find( 'first', array( ‘order_by' => array( ‘updated' => ‘DESC' ) ) );
  22. 22. Model_Collection::find( 'first', array( いらん ‘order_by' => array( ‘updated' => ‘DESC' ) ) );
  23. 23. Model_Collection::find( 'all', array( 'order_by'=>array('updated'=>'DESC') ) ); Model_Collection::find( 'first', array( 'order_by'=>array('updated'=>'DESC') ) );
  24. 24. Model_Collection::find( 'all', array( 'order_by'=>array('updated'=>'DESC') ) ); Model_Collection::find( 'first', array( コピペコードの弊害 'order_by'=>array('updated'=>'DESC') ) );
  25. 25. Model_Collection::find( 'all', array( 'order_by'=>array('updated'=>'DESC') ) ); 返ってきたデータ Model_しCollection::か意識find( 'first', してない array( 'order_by'=>array('updated'=>'DESC') ) );
  26. 26. Model_Collection::find( 'all', array( 'order_by'=>array('updated'=>'DESC') ) ); Model_Collection::find( 'first', array( 生SQLなら防げた? 'order_by'=>array('updated'=>'DESC') ) );
  27. 27. その2
  28. 28. 悪名高きn+1問題
  29. 29. user_profile user_point_log id name sex … 1 goto 1 … 2 ken 2 … 3 gotyoooo 1 … … … … … 10 kenken 1 … … … … … id user_id point … 1 1 10 … 2 2 200 … 3 1 100 … … … … 10 3 30 … … … …
  30. 30. $user = User_Profile::find(‘all', array( ‘where’ => array('sex' => 1) )); $user_point = array(); foreach ($user as $value) { $user_point[] = User_Point_Log::find(‘first’, array( ‘where’ => array(‘user_id' => $value[‘id’]) ) ); }
  31. 31. $user = User_Profile::find(‘all', array( ‘where’ => array('sex' => 1) )); $user_point = array(); foreach ($user as $value) { $user_point[] = User_Point::find(‘first’, array( 余裕かましてると… ‘where’ => array('id' => $value[‘id’]) ) ); }
  32. 32. $user = User_Profile::‘where’ => array('sex' (1) find(‘all', array( => 1) )); $user_point = array(); foreach ($user as $value) { $user_point[] = User_Point::find(‘first’, array( (2) ‘where’ => array('id' => $value[‘id’]) ) ); }
  33. 33. (1) × 1 (2) × n SELECT * FROM user_profile WHERE sex = 1 SELECT * FROM user_point_log WHERE user_id = #id
  34. 34. (1) × 1 (2) × n SELECT * FROM user_profile WHERE sex = 1 無駄なクエリ一杯 SELECT * FROM user_point_log WHERE user_id = #id
  35. 35. (1) × 1 (2) × n SELECT * FROM user_profile WHERE sex = 1 データ数に応じてnも増加 SELECT * FROM user_point_log WHERE user_id = #id
  36. 36. SELECT * FROM user_profile INNER JOIN user_point ON user_profile.id = user_point_log.id WHERE user_profile.sex = 1
  37. 37. SELECT * FROM user_profile INNER JOIN user_point ON user_profile.id = user_point_log.id WHERE user_profile.sex = 1 JOINしましょう
  38. 38. 例 終わり すごい基本な例でごめんなさいorz
  39. 39. 何が言いたいか http://www.canstockphoto.com.br/foto-imagens/eureka.html#file_view.php?id=13126638
  40. 40. http://cyline-jp.com/download/SQL.png http://f.st-hatena.com/images/fotolife/G/GET/20080131/20080131075901.jpg
  41. 41. 投げるクエリを意識すべき http://cyline-jp.com/download/SQL.png http://f.st-hatena.com/images/fotolife/G/GET/20080131/20080131075901.jpg
  42. 42. 意識できる環境を作ろう http://cyline-jp.com/download/SQL.png http://f.st-hatena.com/images/fotolife/G/GET/20080131/20080131075901.jpg
  43. 43. テスト環境にも ある程度のデータ量 http://ja.gofreedownload.net/free-icon/icons/misc-database-109423/#.VDc0idSsWcY
  44. 44. 投げられたSQLを 出力できるような仕組み http://www.tech-faq.com/wp-content/uploads/images/SQL-Injection-Attack.jpg
  45. 45. チーム別スロークエリー 出力ランキングとか素敵 http://www.slot-pioneer.co.jp/product/kingbary/pop/kingbary_08.jpg
  46. 46. 弊社もまだまだ 出来てませんorz http://ja.gofreedownload.net/free-icon/icons/misc-database-109423/#.VDc0idSsWcY http://www.tech-faq.com/wp-content/uploads/images/SQL-Injection-Attack.jpg http://www.slot-pioneer.co.jp/product/kingbary/pop/kingbary_08.jpg
  47. 47. こんなグラフ出す前に
  48. 48. 糞クエリ 撲滅しましょう
  49. 49. ありがとうございました。 ここでドラ娘(?)が鳴らす(予定)

×