Upgrade to Pro — share decks privately, control downloads, hide ads and more …

君も Arel おじさんになって ActiveRecord のクエリを高速化しよう / Let...

君も Arel おじさんになって ActiveRecord のクエリを高速化しよう / Let's become Uncle Arel

森井ゴンザレス

October 12, 2016
Tweet

More Decks by 森井ゴンザレス

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • Kaizen Platform ͱ͍͏ SaaS ͷձࣾʹࡏ੶͍ͯ͠·͢ • Ϩʔϧζྺ5೥͘Β͍ •

    ͓ͬ͞Μ͚ͩͲ ActiveRecord ʢORMʣͳ͍ͱΫΤϦॻ͚ͳ͍ΏͱΓϓϩάϥϚʔͰ͢… ©morygonzalez Fukuoka.rb #66
  2. Kaizen Platform Ͱ΍ͬͯΔ͜ͱ • ͓٬͞ΜͷαΠτʹ JS ೖΕͯ΋Β͏ • A/B ςετ͢Δ

    • ܭଌ͢Δ • BigQuery ʹϩάஷΊΔ • όονͰϩάΛूܭͯ͠ MySQL ʹಥͬࠐΉ • A/B ςετͷ݁ՌΛදࣔ͢Δ • etc. ©morygonzalez Fukuoka.rb #66
  3. MySQL ͷಛੑ • WHERE ۟Ͱ࢖͏ΧϥϜͱ ORDER BY Ͱ sort ͢Δͱ͖ʹ࢖

    ͏ΧϥϜ͕ҟͳΔͱ sort ࣌ʹΠϯσοΫε͕࢖ΘΕͳ͍ ©morygonzalez Fukuoka.rb #66
  4. MySQL ͷಛੑ ͜͏͍͏ͷ͸× CREATE TABLE `users` ( `id` int(11) NOT

    NULL AUTO_INCREMENT, `username` tinyint(1) DEFAULT NULL, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; ALTER TABLE users ADD INDEX index_users_on_username(username); ALTER TABLE users ADD INDEX index_users_on_created_at(created_at); SELECT * FROM users WHERE username = 'foo' ORDER BY created_at; ※͜ͷลద౰ʹॻ͍ͨͷͰؒҧͬͯͨΒ͢Έ·ͤΜ… ©morygonzalez Fukuoka.rb #66
  5. MySQL ͷಛੑ ͜͏͍͏ͷ͸◦ CREATE TABLE `users` ( `id` int(11) NOT

    NULL AUTO_INCREMENT, `username` tinyint(1) DEFAULT NULL, `created_at` datetime NOT NULL, `updated_at` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; ALTER TABLE users ADD INDEX index_users_on_username_and_created_at(username, created_at); SELECT * FROM users WHERE username = 'foo' ORDER BY created_at; ※͜ͷลద౰ʹॻ͍ͨͷͰؒҧͬͯͨΒ͢Έ·ͤΜ… ©morygonzalez Fukuoka.rb #66
  6. 1. ΫΤϦΛ2ճʹ෼͚Δ • ର৅ͷϢʔβʔΛݕࡧ͢ΔΫΤϦΛ౤͛ͯ user id ҰཡΛऔ Δ • ↑Ͱऔಘͨ͠

    id Λ where ۟ʹೖΕͯݕࡧ͠ɺ updated_at ΧϥϜͰ sort ͢Δ • ೋͭͷΫΤϦͱ΋ΠϯσοΫεޮ͍ͯര଎Ͱ͢ ©morygonzalez Fukuoka.rb #66
  7. 2. select ͢ΔΧϥϜΛݮΒ͢ • ActiveRecord ͸ෆඞཁͳΧϥϜ·Ͱશ෦ select ͠·͢ • ͍ͭ͜Λ΍Ίͯ͋͛Δ͚ͩͰ

    1000ms ͘Β͍͔͔ͬͯͨΫΤ Ϧ͕ 500ms ͘Β͍ʹͳΓ·͢ ©morygonzalez Fukuoka.rb #66
  8. 2. select ͢ΔΧϥϜΛݮΒ͢ User. includes(:public_organization). references(:public_organization). where(...) SELECT `users`.`id` AS

    t0_r0, `users`.`username` AS t0_r1, `users`.`email` AS t0_r2, ... FROM users WHERE ... Έ͍ͨͳඇਓؒతͳΫΤϦ͕ੜ੒͞ΕΔ… ©morygonzalez Fukuoka.rb #66
  9. 2. select ͢ΔΧϥϜΛݮΒ͢ User. select( [@users[:id], @users[:username], @users[:allow_public_profile]] ). where(...)

    SELECT users.id, users.username, users.allow_public_profile FROM users WHERE ... ৗࣝతͳΫΤϦʹͳΓ·͢ɻ ©morygonzalez Fukuoka.rb #66