Advertisement

High-Performance Hibernate Devoxx France 2016

Java Champion at https://vladmihalcea.com/
Apr. 21, 2016
Advertisement

More Related Content

Advertisement

High-Performance Hibernate Devoxx France 2016

  1. #DevoxxFR
  2. #DevoxxFR • Hibernate Developer Advocate • vladmihalcea.com • @vlad_mihalcea
  3. #DevoxxFR “More than half of application performance bottlenecks originate in the database” AppDynamics - http://www.appdynamics.com/database/
  4. #DevoxxFR • Connection acquisition time • Data access logic (e.g. entity state transitions) • Statements submission time • Statements execution time • Result set fetching time • Idle time prior to releasing the database connection 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  5. #DevoxxFR • Connection providers • Identifier generators • Relationships • Batching • Fetching • Caching
  6. #DevoxxFR
  7. #DevoxxFR 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  8. #DevoxxFR • Connections acquired lazily • The shorter the transaction lifespan, the higher the transaction throughput
  9. #DevoxxFR
  10. #DevoxxFR 10 50 100 500 1000 5000 10000 0 200 400 600 800 1000 1200 1400 Statement count Time(ms) After statement After transaction
  11. #DevoxxFR <property name="hibernate.connection.release_mode" value="after_transaction"/> • For JTA (e.g. Java EE), try this setting:
  12. #DevoxxFR • AUTO (IDENTITY or SEQUENCE) • IDENTITY • SEQUENCE • TABLE 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  13. #DevoxxFR • Default for SQL Server and MySQL when using AUTO • Disables JDBC batch inserts
  14. #DevoxxFR • Default for Oracle and PostgreSQL when using AUTO • May use roundtrip optimizers: hi/lo, pooled, pooled-lo • Hibernate 5 uses the enhanced sequence generator by default <property name="hibernate.id.new_generator_mappings" value="true"/>
  15. #DevoxxFR 1 5 10 50 0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 Sequence increment size Time(ms)
  16. #DevoxxFR • Uses row-level locks and a separate transaction/connection • May use roundtrip optimizers: hi/lo, pooled, pooled-lo • Hibernate 5 uses the enhanced table generator by default <property name="hibernate.id.new_generator_mappings" value="true"/>
  17. #DevoxxFR 1 5 10 50 0 0.5 1 1.5 2 2.5 3 Table increment size Time(ms)
  18. #DevoxxFR • Identity makes no use of batch inserts • Table generator using an increment size of 100
  19. #DevoxxFR 1 2 4 8 16 0 500 1000 1500 2000 2500 Thread count Time(ms) Identity Table
  20. #DevoxxFR • Both generators use an increment size of 100 1 2 4 8 16 0 200 400 600 800 1000 1200 Thread count Time(ms) Sequence Table
  21. #DevoxxFR 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  22. #DevoxxFR <property name="hibernate.jdbc.batch_size" value="10"/> • SessionFactory configuration • Plan to support Session-level batch size configuration 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  23. #DevoxxFR 1 10 20 30 40 50 60 70 80 90 100 1000 0 200 400 600 800 1000 1200 1400 1600 Batch size Time(ms) DB_A DB_B DB_C DB_D
  24. #DevoxxFR 1 10 20 30 40 50 60 70 80 90 100 1000 0 100 200 300 400 500 600 700 Batch size Time(ms) DB_A DB_B DB_C DB_D
  25. #DevoxxFR 1 10 20 30 40 50 60 70 80 90 100 1000 0 200 400 600 800 1000 1200 Batch size Time(ms) DB_A DB_B DB_C DB_D
  26. #DevoxxFR <property name="hibernate.order_inserts" value="true"/> <property name="hibernate.order_updates" value="true"/> • Plan to support delete statement ordering too
  27. #DevoxxFR <property name="hibernate.jdbc.batch_versioned_data" value="true"/> • Enabled by default in Hibernate 5 • Disabled in Hibernate 3 and 4, Oracle 8i, 9i, and 10g dialects.
  28. #DevoxxFR • JDBC fetch size • JDBC ResultSet size • DTO vs Entity queries • Association fetching 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  29. #DevoxxFR • Oracle – Default fetch size is 10 • SQL Server – Adaptive buffering • PostgreSQL, MySQL – Fetch the whole ResultSet at once • SessionFactory setting: <property name="hibernate.jdbc.fetch_size" value="100"/>
  30. #DevoxxFR • Query-level fetch size setting List<PostCommentSummary> summaries = entityManager.createQuery( "select new PostCommentSummary( " + " p.id, p.title, c.review ) " + "from PostComment c " + "join c.post p") .setHint(QueryHints.HINT_FETCH_SIZE, fetchSize) .getResultList();
  31. #DevoxxFR 1 10 100 1000 10000 0 100 200 300 400 500 600 Fetch size Time(ms) DB_A DB_B DB_C DB_D
  32. #DevoxxFR • Hibernate SQL-level limiting (works for native queries too!) List<PostCommentSummary> summaries = entityManager.createQuery( "select new PostCommentSummary( " + " p.id, p.title, c.review ) " + "from PostComment c " + "join c.post p") .setFirstResult(pageStart) .setMaxResults(pageSize) .getResultList();
  33. #DevoxxFR • 100k Post(s) and + 1M PostComment(s) vs 100 entries Fetch all Fetch limit 0 500 1000 1500 2000 2500 3000 3500 4000 4500 5000 Time(ms) DB_A DB_B DB_C DB_D
  34. #DevoxxFR SELECT * FROM post_comment pc INNER JOIN post p ON p.id = pc.post_id INNER JOIN post_details pd ON p.id = pd.id SELECT pc.version FROM post_comment pc INNER JOIN post p ON p.id = pc.post_id INNER JOIN post_details pd ON p.id = pd.id • Selecting all columns vs selecting a custom projection
  35. #DevoxxFR • 100 Post(s), 100 PostDetail(s) , and 1000 PostComment(s) All columns Custom projection 0 5 10 15 20 25 30 Time(ms) DB_A DB_B DB_C DB_D
  36. #DevoxxFR • Read-only views • Tree structures (Recursive CTE) • Paginated Tables • Analytics (Window functions)
  37. #DevoxxFR • Writing data • Web flows / Multi-request logical transactions • Application-level repeatable reads • Detached entities / PersistenceContextType.EXTENDED • Optimistic concurrency control (e.g. version, dirty properties)
  38. #DevoxxFR
  39. #DevoxxFR “You can turn a Lazy into an Eager, but you cannot turn an Eager into a Lazy”
  40. #DevoxxFR • Default to FetchType.LAZY • Fetch directive in JPQL/Criteria API queries • Entity graphs / @FetchProfile • LazyInitializationException
  41. #DevoxxFR
  42. #DevoxxFR <property name="hibernate.enable_lazy_load_no_trans" value="true"/> • “Band aid” for LazyInitializationException • One temporary Session/Connection for every lazily fetched association
  43. #DevoxxFR 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  44. #DevoxxFR
  45. #DevoxxFR “There are only two hard things in Computer Science: cache invalidation and naming things.” Phil Karlton
  46. #DevoxxFR
  47. #DevoxxFR • Complement entity caching • Store only entity identifiers • Read-Through • Invalidation-based (Consistency over Performance)
  48. #DevoxxFR
  49. #DevoxxFR https://leanpub.com/high-performance-java-persistence 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
Advertisement