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.

Data-centric (SQL) vs Domain-centric (JPA) - JAX 2018

184 views

Published on

This is a presentation that Lukas Eder and I gave at the 2018 JAX conference in Mainz, and it was just awesome.

Published in: Software
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Data-centric (SQL) vs Domain-centric (JPA) - JAX 2018

  1. 1. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 NoSQL? No, SQL! Data centric (SQL)? Domain centric (JPA)? Or both? Let's Discuss!
  2. 2. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Me – @lukaseder SQL is a device whose mystery is only exceeded by its power! - Founder and CEO at Data Geekery - Oracle Java Champion - Oracle ACE
  3. 3. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Me – @vlad_mihalcea JPA is a device whose power is only exceeded by its mystery! - Hibernate Developer Advocate - Oracle Java Champion - High-Performance Java Persistence
  4. 4. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Our context
  5. 5. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Our context - Different background - Working on competing products - But «surprisingly» not disagreeing too much ☺
  6. 6. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Our context
  7. 7. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Our context
  8. 8. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Our context Now is the time ... to follow us (no pressure)
  9. 9. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Domain Centric Our context – Paradigm / Mindset Data Centric
  10. 10. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Record oriented Our context – Paradigm / Mindset Set oriented
  11. 11. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Focus: OLTP Our context – Data Processing Style Focus: OLAP
  12. 12. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Focus: OLTP Our context – Data Processing Style Focus: OLAP (OLTP)
  13. 13. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Object Orientation Our context – Statefulness Functional Programming
  14. 14. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 ORM Our context – Technologies SQL
  15. 15. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 JPA / Hibernate Our context – Specific products jOOQ
  16. 16. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Our context – No Size Fits All
  17. 17. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Two big topics Architecture and Scalability
  18. 18. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Enterprise architecture
  19. 19. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Universal Scalability Law
  20. 20. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Connection pooling Metric DB_A (ms) DB_B (ms) DB_C (ms) DB_D (ms) HikariCP (ms) min 11.174 5.441 24.468 0.860 0.001230 max 129.400 26.110 74.634 74.313 1.014051 mean 13.829 6.477 28.910 1.590 0.003458 p99 20.432 9.944 54.952 3.022 0.010263
  21. 21. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 The anatomy of a database transaction
  22. 22. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Preview – The layers go on in the database Performant logic in the database
  23. 23. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Performance is really simple – @carymillsap https://www.slideshare.net/carymillsap/the-most-important-things-you-should-know-about-oracle/59
  24. 24. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Performance is really simple – @carymillsap This is not specific to databases!
  25. 25. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Example: stored procedures A stored procedure essentially moves a loop from the client to the server. That’s it.
  26. 26. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Microservice friendly
  27. 27. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Example: Oracle Call Latency // Version 1: Loop on the server try (CallableStatement call = c.prepareCall(` DECLARE num integer := ? BEGIN dbms_output.get_lines(?, num); END; `)) { call.setInt(1, size); call.registerOutParameter( 2, Types.ARRAY, "DBMSOUTPUT_LINESARRAY"); call.execute(); ... Loop in here
  28. 28. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Example: Oracle Call Latency // Version 2: Loop in the client for (int i = 0; i < size; i++) { try (CallableStatement call = c.prepareCall(` BEGIN dbms_output.get_line(?, ?); END; `)) { call.registerOutParameter(1, Types.VARCHAR); call.registerOutParameter(2, Types.INTEGER); call.execute(); ... Loop
  29. 29. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Example: Oracle Call Latency // Version 2: Loop in the client for (int i = 0; i < size; i++) { try (CallableStatement call = c.prepareCall(` BEGIN dbms_output.get_line(?, ?); END; `)) { call.registerOutParameter(1, Types.VARCHAR); call.registerOutParameter(2, Types.INTEGER); call.execute(); ... JEP 326: Raw String Literals!
  30. 30. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Example: Oracle Call Latency More details here: https://blog.jooq.org/2017/12/18/the-cost-of-jdbc-server-roundtrips/ Measure 1: Loop on the server 2: Loop in the client Count 50 50 Sum 69.120 🐇 2088.201 🐢 Min 1.068 🐇 33.738 🐢 Avg 1.382 🐇 41.764 🐢 Max 2.455 🐇 64.498 🐢
  31. 31. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Example: stored procedures https://www.slideshare.net/carymillsap/the-most-important-things-you-should-know-about-oracle/59 Still 50 calls But fast ones
  32. 32. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Example: SQL queries A SQL query moves the decision whether to loop to the server. (e.g. hash join vs nested loop join)
  33. 33. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Algorithm adaptation CC BY-SA 2.0 https://www.flickr.com/photos/arkhangellohim/8553142120/
  34. 34. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 My other talk I’ll actually talk about this in my other talk
  35. 35. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Example from my other talk How much money did we earn with each film on each day?
  36. 36. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 SQL: O(N) (as we’re going to run a hash join) SELECT title, store_id, payment_date, SUM(amount) FROM film JOIN inventory USING (film_id) JOIN rental USING (inventory_id) JOIN payment USING (rental_id) GROUP BY film_id, title, store_id, payment_date ORDER BY title, store_id, payment_date 1 query
  37. 37. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Java: O(N^3) (worst case N+1) Map<Film, Map<Integer, Map<LocalDate, BigDecimal>>> result = ...; List<Film> films = loadAllFilms(); for (Film film : films) { Map<Integer, Map<LocalDate, BigDecimal>> dailyPerStore = result.computeIfAbsent(film, k -> new HashMap<>()); for (Inventory inventory : film.getInventories()) { Map<LocalDate, BigDecimal> daily = dailyPerStore.computeIfAbsent( inventory.getStoreId(), k -> new HashMap()); for (Rental rental : inventory.getRentals()) for (Payment p : rental.getPayments()) daily.compute( p.getPaymentDate(), (k, v) -> v == null ? p.getAmount() : p.getAmount().add(v)); } } 1 query N queries N*M queries N*M*O queries
  38. 38. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Interesting talk by @ToonKoppelaars More details here: https://www.youtube.com/watch?v=8jiJDflpw4Y Many layers are traversed
  39. 39. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Interesting talk by @ToonKoppelaars More details here: https://www.youtube.com/watch?v=8jiJDflpw4Y Set-based JDBC would be OK too
  40. 40. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Example: SQL queries https://www.slideshare.net/carymillsap/the-most-important-things-you-should-know-about-oracle/59 Big improvement Better algorithm, because SQL
  41. 41. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 #SmartDB #SmartDB (the opposite extreme to doing everything in Java)
  42. 42. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 A short story on my (@lukaseder) background (before doing jOOQ)
  43. 43. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 SQL centric A lot of business logic written in SQL views
  44. 44. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 An extreme execution plan
  45. 45. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 An extreme execution plan
  46. 46. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 A typical execution plan Example: Downloading file transfer (FT) logs
  47. 47. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 A typical execution plan FT log stuff Payment Archive Currency conversion Account Access Control FT Access Control
  48. 48. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Orders of magnitude FT log stuff 10M Rows Payment Archive 1G Rows Currency conversion 100K Rows Account Access Control 100M Rows FT Access Control 100M Rows
  49. 49. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Around 0.1 sessions are busy with this query at any time A typical execution plan
  50. 50. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 A typical execution plan A single execution takes on average 10.73ms Room for optimisation This is actually slow!
  51. 51. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 A typical execution plan But the system is quite fine. 4M total users 300k daily logins
  52. 52. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Reminds me of https://nickcraver.com/blog/2016/02/17/stack-overflow-the-architecture-2016-edition/ Lots of queries Low response time
  53. 53. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Reminds me of https://www.periscopedata.com/blog/count-distinct-in-mysql-postgres-sql-server-and-oracle
  54. 54. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Let’s talk about a core piece of business logic, implemented in SQL Remember that Access Control?
  55. 55. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Remember that Access Control?Essentially, contracts are granted access to products owned by customers
  56. 56. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Example CONT_ID PROD_ID CUST_ID 1 10 1 11 1 12 2 10 3 (all of 100’s products) 100
  57. 57. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 How to do it? With a view! CREATE VIEW v_contract_rights AS SELECT cori_id, cont_id, cust_id, prod_id FROM contract_rights cori JOIN products prod ON prod.prod_id = cori.prod_id JOIN customers cust ON cust.cust_id = prod.cust_id WHERE cont_id = SYS_CONTEXT('APP', 'CONT_ID') Transaction-scoped variable
  58. 58. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 How to do it? With a view! CREATE VIEW v_contract_rights AS SELECT cori_id, cont_id, cust_id, prod_id FROM contract_rights cori JOIN products prod ON prod.prod_id = cori.prod_id JOIN customers cust ON cust.cust_id = prod.cust_id WHERE cont_id = SYS_CONTEXT('APP', 'CONT_ID') I can see only «my data»
  59. 59. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 How to do it? With a view! CREATE VIEW v_contract_rights AS SELECT cori_id, cont_id, cust_id, prod_id FROM contract_rights cori JOIN products prod ON prod.prod_id = cori.prod_id JOIN customers cust ON cust.cust_id = prod.cust_id WHERE cont_id = SYS_CONTEXT('APP', 'CONT_ID') UNION ALL SELECT cori_id, cont_id, cust_id, prod_id FROM contract_rights cori JOIN products prod ON prod.cust_id = cori.cust_id WHERE cont_id = SYS_CONTEXT('APP', 'CONT_ID') AND cori.prod_id IS NULL Individual Product Access Complete Customer Access
  60. 60. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Now join this view everywhere Account Access Control FT Access Control
  61. 61. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 In fact, views are everywhere, like functions View View View View View View
  62. 62. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Advantages - Very performant (in Oracle) - Security in the database - Reusable logic - Easy to change Come see my other talk
  63. 63. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Caveats - Very performant (in Oracle) - Security in the database - Reusable logic - Easy to change Can be done extensively in commercial DBs. To some extent in PostgreSQL. Probably not in MySQL.
  64. 64. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Key message These were OLTP queries, not OLAP / analytics / reports / ETL. SQL is a very good language for business logic.
  65. 65. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Key message • Nothing I’ve shown is extra-ordinary.
  66. 66. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Key message • Nothing I’ve shown is extra-ordinary. • You’re doing this as well.
  67. 67. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Key message • Nothing I’ve shown is extra-ordinary. • You’re doing this as well. • But you’re doing it in Java, not in SQL.
  68. 68. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Key message • Nothing I’ve shown is extra-ordinary. • You’re doing this as well. • But you’re doing it in Java, not in SQL. • Should you really do it in Java?
  69. 69. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Key message Think outside the box
  70. 70. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Key message
  71. 71. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Key message
  72. 72. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 This is a recurring pattern https://www.slideshare.net/carymillsap/the-most-important-things-you-should-know-about-oracle/59 Huge decrease here Also better, because SQL
  73. 73. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 But one size doesn’t fit all But also in this system, not everything was written in SQL. In fact, a single user click may generate dozens of these queries.
  74. 74. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 But one size doesn’t fit all And we haven’t discussed writing to the database yet!
  75. 75. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 How about Event Sourcing and CQRS? Aren’t we suppose to store immutable events (facts) in our database? Is writing data still a thing in 2018?
  76. 76. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Google Spanner https://static.googleusercontent.com/media/research.google.com/en//archive/spanner-osdi2012.pdf
  77. 77. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Write-behind caching
  78. 78. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Lazy connection acquisition
  79. 79. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Lazy connection acquisition https://www.slideshare.net/carymillsap/the-most-important-things-you-should-know-about-oracle/59 Decreases this part
  80. 80. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Automatic JDBC statement batching 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
  81. 81. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Lazy connection acquisition https://www.slideshare.net/carymillsap/the-most-important-things-you-should-know-about-oracle/59 Decreases this part
  82. 82. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 But there’s more than batch: Bulk DML! Which one will perform better? UPDATE post SET archived = 1 WHERE archived = 0 AND creation_date < DATE '2018-01-01' try (Statement s = con.createStatement(); ResultSet rs = s.executeQuery(` SELECT id FROM post WHERE archived = 0 AND creation_date < DATE '2018-01-01' `); PreparedStatement u = con.prepareStatement(` UPDATE post SET archived = 1 WHERE id = ? `)) { while (rs.next()) { u.setInt(1, rs.getInt(1)); u.executeUpdate(); } } Single statement N+1 with JDBC
  83. 83. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 But there’s more than batch: Bulk DML! Which one will perform better? UPDATE post SET archived = 1 WHERE archived = 0 AND creation_date < DATE '2018-01-01' Single statement FOR rec IN ( SELECT id FROM post WHERE archived = 0 AND creation_date < DATE '2018-01-01' ) LOOP UPDATE post SET archived = 1 WHERE id = rec.id; END LOOP; Or in PL/SQL
  84. 84. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Bulk DML benchmark results Measure Time LOOP 0.224 🐓 FORALL 0.100 🐇 BULK UPDATE 0.065 🐇 Measure Time LOOP (PreparedStatement per iteration) 9.302 🐢 LOOP (PreparedStatement reused) 8.182 🐢 Batch 0.346 🐓 Bulk UPDATE 0.066 🐇 PL/SQL More details here: https://blog.jooq.org/2018/04/19/the-performance-difference-between- sql-row-by-row-updating-batch-updating-and-bulk-updating/ Java
  85. 85. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 JDBC fetch size List<PostCommentSummary> summaries = em.createQuery( `select new PostCommentSummary( p.id, p.title, c.review ) from PostComment c join c.post p`) .setHint(QueryHints.HINT_FETCH_SIZE, fetchSize) .getResultList();
  86. 86. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 JDBC fetch size 1 10 100 1000 10000 0 100 200 300 400 500 600 Fetch size Time(ms) DB_A DB_B DB_C DB_D
  87. 87. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Lazy connection acquisition https://www.slideshare.net/carymillsap/the-most-important-things-you-should-know-about-oracle/59 You’ve guessed it
  88. 88. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 JDBC Result Set pagination List<PostCommentSummary> summaries = em.createQuery( `select new PostCommentSummary( p.id, p.title, c.review ) from PostComment c join c.post p`) .setFirstResult(pageStart) .setMaxResults(pageSize) .getResultList();
  89. 89. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 JDBC Result Set pagination – 100k vs 100 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
  90. 90. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 What’s wrong with this? List<PostCommentSummary> summaries = em.createQuery( `select new PostCommentSummary( p.id, p.title, c.review ) from PostComment c join c.post p`) .setFirstResult(pageStart) .setMaxResults(pageSize) .getResultList();
  91. 91. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Try not to use OFFSET Pagination List<PostCommentSummary> summaries = em.createQuery( `select new PostCommentSummary( p.id, p.title, c.review ) from PostComment c join c.post p`) .setFirstResult(pageStart) .setMaxResults(pageSize) .getResultList();
  92. 92. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Try not to use OFFSET Pagination Offset skips rows in: - O(N) if an index is used for ORDER BY - O(N log N) otherwise! Source: https://use-the-index-luke.com/no-offset
  93. 93. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Pagination vs Narrowing down
  94. 94. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Pagination vs Narrowing down
  95. 95. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 JDBC Result Set column count 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.review, p.title, pd.created_on FROM post_comment pc INNER JOIN post p ON p.id = pc.post_id INNER JOIN post_details pd ON p.id = pd.id
  96. 96. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 JDBC Result Set column count All columns Custom projection 0 5 10 15 20 25 30 Time(ms) DB_A DB_B DB_C DB_D
  97. 97. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Lazy connection acquisition https://www.slideshare.net/carymillsap/the-most-important-things-you-should-know-about-oracle/59 So we’re here again
  98. 98. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Let’s look at execution plans, too SELECT pc.review, p.title, pd.created_on FROM post_comment pc INNER JOIN post p ON p.id = pc.post_id INNER JOIN post_details pd ON p.id = pd.id
  99. 99. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Let’s look at execution plans, too SELECT pc.review, p.title, pd.created_on FROM post_comment pc INNER JOIN post p ON p.id = pc.post_id INNER JOIN post_details pd ON p.id = pd.id CREATE INDEX i ON post (id, title) No more post table access
  100. 100. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Let’s look at execution plans, too SELECT pc.review, p.title, pd.created_on FROM post_comment pc INNER JOIN post p ON p.id = pc.post_id INNER JOIN post_details pd ON p.id = pd.id No more join on post!
  101. 101. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Let’s look at execution plans, too SELECT pc.review, p.title, pd.created_on FROM post_comment pc INNER JOIN post p ON p.id = pc.post_id INNER JOIN post_details pd ON pc.post_id = pd.id As if it were eliminated manually
  102. 102. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Rule of thumb When you need to write data back to the database, entities are very useful. For read-only data, you should always use projections!
  103. 103. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Caching
  104. 104. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Application-level concurrency control
  105. 105. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Concurrency Control Patterns - Come see my other talk
  106. 106. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 … of the same coin Concluding... Two sides
  107. 107. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Concluding… There isn’t really a better approach or a better perspective.
  108. 108. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Concluding… It’s just logic, distributed between client and server.
  109. 109. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Use the right tool CC BY 2.0 - https://www.flickr.com/photos/justinbaeder/5317820857/
  110. 110. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 We promised
  111. 111. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 We gave you
  112. 112. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Not that this is any news FYI: Gavin King: Creator of Hibernate!
  113. 113. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0 Thank you Check out our trainings: http://www.jooq.org/training https://vladmihalcea.com/courses Coordinates • Blogs: http://blog.jooq.org, http:// vladmihalcea.com • Twitter: @lukaseder, @vlad_mihalcea • Book: https://leanpub.com/high-performance-java-persistence

×