fix formatting:

This commit is contained in:
Rawley
2023-11-30 17:54:47 -06:00
parent faa980b323
commit eaaf1cf431
2 changed files with 7 additions and 10 deletions

View File

@@ -22,7 +22,6 @@
<li> <li>
<a href="/jpa-hibernate-stupid-performance.html">Making JPA Repository stupid fast with Entity Graph</a> <a href="/jpa-hibernate-stupid-performance.html">Making JPA Repository stupid fast with Entity Graph</a>
</li> </li>
<li>
<li> <li>
<a href="/docker-mod-perl.html">Running Mojolicious with <code>mod_perl</code> in Docker</a> <a href="/docker-mod-perl.html">Running Mojolicious with <code>mod_perl</code> in Docker</a>
</li> </li>

View File

@@ -20,25 +20,24 @@
</p> </p>
<h2 id="go-fast">Time to go fast</h2> <h2 id="go-fast">Time to go fast</h2>
<p> <p>
By enabling <pre><code>logging.level.org.hibernate.SQL=DEBUG</code></pre> and <pre><code>logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE</code></pre>, By enabling <pre><code>logging.level.org.hibernate.SQL=DEBUG</code></pre> and <pre><code>logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE</code></pre>
you're able to see the ridiculous number queries JPA is executing, they're un-countable, there's so many!! How can we fix this? you're able to see the ridiculous number queries JPA is executing, they're un-countable, there's so many!! How can we fix this?
</p> </p>
<p> <p>
If you're thinking of using <pre><code>@Batch(100)</code></pre>, it could work, only issue is JPA will batch each relationship, so each of our tables will still require If you're thinking of using <code>@Batch(100)</code>, it could work, only issue is JPA will batch each relationship, so each of our tables will still require
<pre><code>n/100</code></pre> calls where <pre><code>n</code></pre> is the number of rows with relationships. So theoretically a 100x speed bump right? Well, it's actually more <code>n/100</code> calls where <code>n</code> is the number of rows with relationships. So theoretically a 100x speed bump right? Well, it's actually more
like a 33x performance bump, since you still have the overhead of making the database connections, and need to get a lock every time you select. Doing this we moved to around like a 33x performance bump, since you still have the overhead of making the database connections, and need to get a lock every time you select. Doing this we moved to around
3-5 minutes depending on load per large call. This however, was still unacceptable. 3-5 minutes depending on load per large call. This however, was still unacceptable.
</p> </p>
<p> <p>
What if instead we just forced JPA to use <pre><code>OUTER JOIN</code></pre>? Isn't that exactly what the ANSI SQL wizards would tell you to do? What if instead we just forced JPA to use <code>OUTER JOIN</code>? Isn't that exactly what the ANSI SQL wizards would tell you to do?
Obviously, this is the solution, one single connection, 1 lock, and let the B-Tree optimizations inside of the database handle all of this ugliness for us. Obviously, this is the solution, one single connection, 1 lock, and let the B-Tree optimizations inside of the database handle all of this ugliness for us.
To do this you need to use something called <a href="https://www.baeldung.com/jpa-entity-graph"><pre><code>@EntityGraph</code></pre></a> To do this you need to use something called <a href="https://www.baeldung.com/jpa-entity-graph"><code>@EntityGraph</code></a>
on your JPA repository, what this does is forces JPA to use a <pre><code>OUTER JOIN</code></pre> on your JPA repository, what this does is forces JPA to use a <code>OUTER JOIN</code>
to join relationships. This even works on nested entities, say I have Entity A with a child B which also has a One-to-Many on C, all you need to do to join relationships. This even works on nested entities, say I have Entity A with a child B which also has a One-to-Many on C, all you need to do
is add the relationship to the entity graph with the <pre><code>@NamedEntityGraph</code></pre> annotation, then provide it with a few nice args like name, is add the relationship to the entity graph with the <code>@NamedEntityGraph</code> annotation, then provide it with a few nice args like name,
and attributeNodes which will point to your sub entity. Then finally on your JPA repository call you stitch the entity graph back together. and attributeNodes which will point to your sub entity. Then finally on your JPA repository call you stitch the entity graph back together.
</p> </p>
<p>
<pre> <pre>
<code> <code>
@Repository @Repository
@@ -49,7 +48,6 @@ public interface ARepository extends JpaRepository<A, UUID>, JpaSpecificationExe
} }
</code> </code>
</pre> </pre>
</p>
<p> <p>
After applying these, the query time went down from 15 minutes to ... *drum-roll* ... 3 seconds. So please, for the love of all that is computationally efficient, force your JPA After applying these, the query time went down from 15 minutes to ... *drum-roll* ... 3 seconds. So please, for the love of all that is computationally efficient, force your JPA
to use <pre><code>OUTER JOIN</code></pre>, or even roll your own SQL, ORM's really are one of the biggest trade-offs, and they really can bite you. This is why tend to to use <pre><code>OUTER JOIN</code></pre>, or even roll your own SQL, ORM's really are one of the biggest trade-offs, and they really can bite you. This is why tend to