Skip to content

Commit

Permalink
Improve PG performance by 28% (!!!) (#703)
Browse files Browse the repository at this point in the history
A very long overdue PostgreSQL querying performance optimization that
should have used cached queries, but ... somehow didn't.

Also, this PR adds two new `just` tasks: `run-release` and `bench-http`

I used [oha](https://github.com/hatoo/oha) for its visual appeal. All
tests were using keep-alive, which I think is relatively accurate
because clients make many tile requests on the same connection. As a
target, I used the same non-empty small tile to reduce the PostgreSQL
indexing load.

❯ just run-release
❯ just bench-http

`bench-http` runs this command:
```
oha -z 120s http://localhost:3000/function_zxy_query/18/235085/122323
```

<pre>
|       before the change          |         after the change         |
|----------------------------------|----------------------------------|
|   Summary:                       | Summary:                         |
|     Success rate:    1.0000      |   Success rate:    1.0000        |
|     Total:    120.0004 secs      |   Total:    120.0002 secs        |
|     Slowest:    0.1339 secs      |   Slowest:    0.3505 secs        |
|     Fastest:    0.0015 secs      |   Fastest:    0.0012 secs        |
|     Average:    0.0076 secs      |   Average:    0.0055 secs        |
|     Requests/sec:    6583.6946   |   Requests/sec:    9073.5398     |
|                                  |                                  |
|     Total data:    113.02 MiB    |   Total data:    155.76 MiB      |
|     Size/request:    150 B       |   Size/request:    150 B         |
|     Size/sec:    964.41 KiB      |   Size/sec:    1.30 MiB          |
|                                  |                                  |
|   Response time histogram:       | Response time histogram:         |
|     0.002 [1]                    |   0.001 [1]                      |
|     0.015 [785706] ■■■■■■■■■■■■■ |   0.036 [1088825] ■■■■■■■■■■■■■  |
|     0.028 [4225]                 |   0.071 [0]                      |
|     0.041 [111]                  |   0.106 [0]                      |
|     0.054 [2]                    |   0.141 [0]                      |
|     0.068 [0]                    |   0.176 [0]                      |
|     0.081 [0]                    |   0.211 [0]                      |
|     0.094 [0]                    |   0.246 [0]                      |
|     0.107 [0]                    |   0.281 [0]                      |
|     0.121 [0]                    |   0.316 [0]                      |
|     0.134 [1]                    |   0.350 [1]                      |
|                                  |                                  |
|   Latency distribution:          | Latency distribution:            |
|     10% in 0.0057 secs           |   10% in 0.0039 secs             |
|     25% in 0.0064 secs           |   25% in 0.0045 secs             |
|     50% in 0.0073 secs           |   50% in 0.0053 secs             |
|     75% in 0.0084 secs           |   75% in 0.0063 secs             |
|     90% in 0.0098 secs           |   90% in 0.0074 secs             |
|     95% in 0.0107 secs           |   95% in 0.0082 secs             |
|     99% in 0.0135 secs           |   99% in 0.0102 secs             |
</pre>

Fixes #678
  • Loading branch information
nyurik authored Jun 4, 2023
1 parent adab3bc commit 6d02416
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 8 deletions.
2 changes: 2 additions & 0 deletions docs/src/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ When developing MBTiles SQL code, you may need to use `just prepare-sqlite` when
❯ just
Available recipes:
run *ARGS # Start Martin server and a test database
run-release *ARGS # Start release-compiled Martin server and a test database
debug-page *ARGS # Start Martin server and open a test page
psql *ARGS # Run PSQL utility against the test database
clean # Perform cargo clean to delete all build files
Expand All @@ -40,6 +41,7 @@ Available recipes:
start-legacy # Start a legacy test database
stop # Stop the test database
bench # Run benchmark tests
bench-http # Run HTTP requests benchmark using OHA tool. Use with `just run-release`
test # Run all tests using a test database
test-ssl # Run all tests using an SSL connection to a test database. Expected output won't match.
test-legacy # Run all tests using the oldest supported version of the database
Expand Down
15 changes: 15 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export CARGO_TERM_COLOR := "always"
run *ARGS: start
cargo run -- {{ ARGS }}

# Start release-compiled Martin server and a test database
run-release *ARGS: start
cargo run -- {{ ARGS }}

# Start Martin server and open a test page
debug-page *ARGS: start
open tests/debug.html # run will not exit, so open debug page first
Expand Down Expand Up @@ -60,6 +64,17 @@ stop:
bench: start
cargo bench

# Run HTTP requests benchmark using OHA tool. Use with `just run-release`
bench-http:
@echo "Make sure Martin was started with 'just run-release'"
@if ! command -v oha &> /dev/null; then \
echo "oha could not be found. Installing..." ;\
cargo install oha ;\
fi
@echo "Warming up..."
oha -z 5s --no-tui http://localhost:3000/function_zxy_query/18/235085/122323 > /dev/null
oha -z 120s http://localhost:3000/function_zxy_query/18/235085/122323

# Run all tests using a test database
test: (docker-up "db") test-unit test-int

Expand Down
19 changes: 11 additions & 8 deletions martin/src/pg/pg_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,17 @@ impl Source for PgSource {
};

let query = &self.info.query;
let prep_query = conn.prepare_typed(query, param_types).await.map_err(|e| {
PrepareQueryError(
e,
self.id.to_string(),
self.info.signature.to_string(),
self.info.query.to_string(),
)
})?;
let prep_query = conn
.prepare_typed_cached(query, param_types)
.await
.map_err(|e| {
PrepareQueryError(
e,
self.id.to_string(),
self.info.signature.to_string(),
self.info.query.to_string(),
)
})?;

let tile = if self.support_url_query() {
let json = query_to_json(url_query);
Expand Down

0 comments on commit 6d02416

Please sign in to comment.