This year, the SQL language will celebrate its 32nd birthday. Hibernate turns 17 years old, JPA 12 years old, and jOOQ 10 years old. All these technologies are established, mature, and we know how they work. Or do we? In 2018, we are still having many heated discussions about how to persist our data, how to query it, how to model our transactions, how to model our domains. In the Java ecosystem, SQL-centric systems are often seen as "legacy", whereas JPA-centric ones as "modern" (or standard if we consider JPA). Given the ages of these technologies, this seems understandable. But is it reasonable? The SQL approach is more bulk data processing oriented (OLAP), whereas the JPA approach is more CRUD oriented (OLTP). SQL is more stateless/sessionless/side-effect free whereas JPA is stateful/sessionful/imperative. SQL runs set-based computational logic in the database, giving access to the sophistication of modern SQL optimisers, whereas JPA offers running record-based computational logic in the client, giving access to the vast possibilities of Java libraries and client-side processing. In this talk, Vlad (from Hibernate) and Lukas (from jOOQ) will discuss the pros and cons of each paradigm.
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Data centric (SQL)? Domain centric (JPA)? Or both? Let's Discuss!
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. 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. 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. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Our context
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. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Our context
7. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Our context
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. 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. 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. 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. 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. 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. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
ORM
Our context – Technologies
SQL
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. 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. 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. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Enterprise architecture
19. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Universal Scalability Law
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. 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. 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. 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. 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. 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. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Microservice friendly
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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
An extreme execution plan
45. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
An extreme execution plan
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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Key message
71. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Key message
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. 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. 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. 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. 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. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Write-behind caching
78. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Lazy connection acquisition
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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Pagination vs Narrowing down
94. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Pagination vs Narrowing down
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. 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. 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. 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. 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. 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. 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. 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. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Caching
104. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
Application-level concurrency control
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. 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. 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. 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. 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. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
We promised
111. Copyright (c) 2018 by Data Geekery GmbH and Hypersistence SRL. Slides licensed under CC BY SA 3.0
We gave you
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. 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