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.
#DevoxxFR
#DevoxxFR
• Hibernate Developer Advocate
• vladmihalcea.com
• @vlad_mihalcea
#DevoxxFR
“More than half of application
performance bottlenecks originate
in the database”
AppDynamics - http://www.appdy...
#DevoxxFR
• Connection acquisition time
• Data access logic (e.g. entity state transitions)
• Statements submission time
•...
#DevoxxFR
• Connection providers
• Identifier generators
• Relationships
• Batching
• Fetching
• Caching
#DevoxxFR
#DevoxxFR
𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
#DevoxxFR
• Connections acquired lazily
• The shorter the transaction lifespan, the higher the transaction
throughput
#DevoxxFR
#DevoxxFR
10 50 100 500 1000 5000 10000
0
200
400
600
800
1000
1200
1400
Statement count
Time(ms)
After statement After tr...
#DevoxxFR
<property name="hibernate.connection.release_mode" value="after_transaction"/>
• For JTA (e.g. Java EE), try thi...
#DevoxxFR
• AUTO (IDENTITY or SEQUENCE)
• IDENTITY
• SEQUENCE
• TABLE
𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
#DevoxxFR
• Default for SQL Server and MySQL when using AUTO
• Disables JDBC batch inserts
#DevoxxFR
• Default for Oracle and PostgreSQL when using AUTO
• May use roundtrip optimizers: hi/lo, pooled, pooled-lo
• H...
#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)
#DevoxxFR
• Uses row-level locks and a separate transaction/connection
• May use roundtrip optimizers: hi/lo, pooled, pool...
#DevoxxFR
1 5 10 50
0
0.5
1
1.5
2
2.5
3
Table increment size
Time(ms)
#DevoxxFR
• Identity makes no use of batch inserts
• Table generator using an increment size of 100
#DevoxxFR
1 2 4 8 16
0
500
1000
1500
2000
2500
Thread count
Time(ms)
Identity Table
#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)
Sequ...
#DevoxxFR
𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
#DevoxxFR
<property name="hibernate.jdbc.batch_size" value="10"/>
• SessionFactory configuration
• Plan to support Session...
#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 D...
#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
#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
#DevoxxFR
<property name="hibernate.order_inserts" value="true"/>
<property name="hibernate.order_updates" value="true"/>
...
#DevoxxFR
<property name="hibernate.jdbc.batch_versioned_data" value="true"/>
• Enabled by default in Hibernate 5
• Disabl...
#DevoxxFR
• JDBC fetch size
• JDBC ResultSet size
• DTO vs Entity queries
• Association fetching
𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞...
#DevoxxFR
• Oracle – Default fetch size is 10
• SQL Server – Adaptive buffering
• PostgreSQL, MySQL – Fetch the whole Resu...
#DevoxxFR
• Query-level fetch size setting
List<PostCommentSummary> summaries = entityManager.createQuery(
"select new Pos...
#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
#DevoxxFR
• Hibernate SQL-level limiting (works for native queries too!)
List<PostCommentSummary> summaries = entityManage...
#DevoxxFR
• 100k Post(s) and + 1M PostComment(s) vs 100 entries
Fetch all Fetch limit
0
500
1000
1500
2000
2500
3000
3500
...
#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
...
#DevoxxFR
• 100 Post(s), 100 PostDetail(s) , and 1000 PostComment(s)
All columns Custom projection
0
5
10
15
20
25
30
Time...
#DevoxxFR
• Read-only views
• Tree structures (Recursive CTE)
• Paginated Tables
• Analytics (Window functions)
#DevoxxFR
• Writing data
• Web flows / Multi-request logical transactions
• Application-level repeatable reads
• Detached ...
#DevoxxFR
#DevoxxFR
“You can turn a Lazy into an
Eager, but you cannot turn an
Eager into a Lazy”
#DevoxxFR
• Default to FetchType.LAZY
• Fetch directive in JPQL/Criteria API queries
• Entity graphs / @FetchProfile
• Laz...
#DevoxxFR
#DevoxxFR
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
• “Band aid” for LazyInitializationException...
#DevoxxFR
𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
#DevoxxFR
#DevoxxFR
“There are only two hard things in
Computer Science: cache
invalidation and naming things.”
Phil Karlton
#DevoxxFR
#DevoxxFR
• Complement entity caching
• Store only entity identifiers
• Read-Through
• Invalidation-based (Consistency ove...
#DevoxxFR
#DevoxxFR
https://leanpub.com/high-performance-java-persistence
𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
Upcoming SlideShare
Loading in …5
×

High-Performance Hibernate Devoxx France 2016

12,385 views

Published on

The High-Performance Hibernate presentation from Devoxx France 2016

Published in: Software
  • Be the first to comment

High-Performance Hibernate Devoxx France 2016

  1. 1. #DevoxxFR
  2. 2. #DevoxxFR • Hibernate Developer Advocate • vladmihalcea.com • @vlad_mihalcea
  3. 3. #DevoxxFR “More than half of application performance bottlenecks originate in the database” AppDynamics - http://www.appdynamics.com/database/
  4. 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. 5. #DevoxxFR • Connection providers • Identifier generators • Relationships • Batching • Fetching • Caching
  6. 6. #DevoxxFR
  7. 7. #DevoxxFR 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  8. 8. #DevoxxFR • Connections acquired lazily • The shorter the transaction lifespan, the higher the transaction throughput
  9. 9. #DevoxxFR
  10. 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. 11. #DevoxxFR <property name="hibernate.connection.release_mode" value="after_transaction"/> • For JTA (e.g. Java EE), try this setting:
  12. 12. #DevoxxFR • AUTO (IDENTITY or SEQUENCE) • IDENTITY • SEQUENCE • TABLE 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  13. 13. #DevoxxFR • Default for SQL Server and MySQL when using AUTO • Disables JDBC batch inserts
  14. 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. 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. 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. 17. #DevoxxFR 1 5 10 50 0 0.5 1 1.5 2 2.5 3 Table increment size Time(ms)
  18. 18. #DevoxxFR • Identity makes no use of batch inserts • Table generator using an increment size of 100
  19. 19. #DevoxxFR 1 2 4 8 16 0 500 1000 1500 2000 2500 Thread count Time(ms) Identity Table
  20. 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. 21. #DevoxxFR 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  22. 22. #DevoxxFR <property name="hibernate.jdbc.batch_size" value="10"/> • SessionFactory configuration • Plan to support Session-level batch size configuration 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  23. 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. 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. 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. 26. #DevoxxFR <property name="hibernate.order_inserts" value="true"/> <property name="hibernate.order_updates" value="true"/> • Plan to support delete statement ordering too
  27. 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. 28. #DevoxxFR • JDBC fetch size • JDBC ResultSet size • DTO vs Entity queries • Association fetching 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  29. 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. 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. 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. 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. 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. 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. 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. 36. #DevoxxFR • Read-only views • Tree structures (Recursive CTE) • Paginated Tables • Analytics (Window functions)
  37. 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. 38. #DevoxxFR
  39. 39. #DevoxxFR “You can turn a Lazy into an Eager, but you cannot turn an Eager into a Lazy”
  40. 40. #DevoxxFR • Default to FetchType.LAZY • Fetch directive in JPQL/Criteria API queries • Entity graphs / @FetchProfile • LazyInitializationException
  41. 41. #DevoxxFR
  42. 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. 43. #DevoxxFR 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒
  44. 44. #DevoxxFR
  45. 45. #DevoxxFR “There are only two hard things in Computer Science: cache invalidation and naming things.” Phil Karlton
  46. 46. #DevoxxFR
  47. 47. #DevoxxFR • Complement entity caching • Store only entity identifiers • Read-Through • Invalidation-based (Consistency over Performance)
  48. 48. #DevoxxFR
  49. 49. #DevoxxFR https://leanpub.com/high-performance-java-persistence 𝑇 = 𝑡 𝑎𝑐𝑞 + 𝑡 𝑑𝑎𝑙 + 𝑡 𝑟𝑒𝑞 + 𝑡 𝑒𝑥𝑒𝑐 + 𝑡 𝑟𝑒𝑠 + 𝑡𝑖𝑑𝑙𝑒

×