Skip to content

Commit d5e1177

Browse files
committed
Optimize SQL generation
1 parent 785b9fd commit d5e1177

File tree

7 files changed

+814
-720
lines changed

7 files changed

+814
-720
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- MySQL adapter [#5](https://github.com/elixir-dbvisor/sql/pull/5).
1616
- PostgreSQL adapter [#5](https://github.com/elixir-dbvisor/sql/pull/5).
1717
- TDS adapter [#5](https://github.com/elixir-dbvisor/sql/pull/5).
18+
- Improve SQL generation with 600x compared to Ecto [#7](https://github.com/elixir-dbvisor/sql/pull/7).
1819

1920
### Deprecation
2021
- token_to_sql/2 is deprecated in favor of SQL.Token behaviour token_to_string/2 [#5](https://github.com/elixir-dbvisor/sql/pull/5).

bench.exs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
11
import SQL
2+
import Ecto.Query
3+
defmodule SQL.Repo do
4+
use Ecto.Repo, otp_app: :sql, adapter: Ecto.Adapters.Postgres
5+
end
6+
Application.put_env(:sql, :ecto_repos, [SQL.Repo])
7+
Application.put_env(:sql, SQL.Repo, username: "postgres", password: "postgres", hostname: "localhost", database: "sql_test#{System.get_env("MIX_TEST_PARTITION")}", pool: Ecto.Adapters.SQL.Sandbox, pool_size: 10)
8+
SQL.Repo.start_link()
9+
210
range = 1..10_000
11+
sql = ~SQL[with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)]
12+
query = "temp" |> recursive_ctes(true) |> with_cte("temp", as: ^union_all(select("temp", [t], %{n: 0, fact: 1}), ^where(select("temp", [t], [t.n+1, t.n+1*t.fact]), [t], t.n < 9))) |> select([t], [t.n])
313
Benchee.run(
414
%{
5-
"to_stirng" => fn -> for _ <- range, do: to_string(~SQL[with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)]) end,
6-
"to_sql" => fn -> for _ <- range, do: SQL.to_sql(~SQL[with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)]) end,
7-
"inspect" => fn -> for _ <- range, do: inspect(~SQL[with recursive temp (n, fact) as (select 0, 1 union all select n+1, (n+1)*fact from temp where n < 9)]) end
15+
"to_stirng" => fn -> for _ <- range, do: to_string(sql) end,
16+
"to_sql" => fn -> for _ <- range, do: SQL.to_sql(sql) end,
17+
"inspect" => fn -> for _ <- range, do: inspect(sql) end,
18+
"Ecto.Repo.to_sql" => fn -> for _ <- range, do: SQL.Repo.to_sql(:all, query) end
819
},
920
time: 10,
1021
memory_time: 2

benchmarks/v0.2.0.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
➜ sql git:(optimize-sql-generation) ✗ mix sql.bench
2+
Compiling 1 file (.ex)
3+
Generated sql app
4+
Operating System: macOS
5+
CPU Information: Apple M1 Max
6+
Number of Available Cores: 10
7+
Available memory: 64 GB
8+
Elixir 1.18.0
9+
Erlang 27.2
10+
JIT enabled: true
11+
12+
Benchmark suite executing with the following configuration:
13+
warmup: 2 s
14+
time: 10 s
15+
memory time: 2 s
16+
reduction time: 0 ns
17+
parallel: 1
18+
inputs: none specified
19+
Estimated total run time: 56 s
20+
21+
Benchmarking Ecto.Repo.to_sql ...
22+
Benchmarking inspect ...
23+
Benchmarking to_sql ...
24+
Benchmarking to_stirng ...
25+
Calculating statistics...
26+
Formatting results...
27+
28+
Name ips average deviation median 99th %
29+
to_sql 4.74 K 0.21 ms ±20.20% 0.20 ms 0.32 ms
30+
to_stirng 4.51 K 0.22 ms ±3.60% 0.22 ms 0.26 ms
31+
inspect 0.24 K 4.09 ms ±2.96% 4.09 ms 4.36 ms
32+
Ecto.Repo.to_sql 0.00757 K 132.03 ms ±1.45% 131.80 ms 139.43 ms
33+
34+
Comparison:
35+
to_sql 4.74 K
36+
to_stirng 4.51 K - 1.05x slower +0.0108 ms
37+
inspect 0.24 K - 19.39x slower +3.88 ms
38+
Ecto.Repo.to_sql 0.00757 K - 626.20x slower +131.82 ms
39+
40+
Memory usage statistics:
41+
42+
Name Memory usage
43+
to_sql 0.38 MB
44+
to_stirng 0.153 MB - 0.40x memory usage -0.22888 MB
45+
inspect 4.88 MB - 12.80x memory usage +4.50 MB
46+
Ecto.Repo.to_sql 179.35 MB - 470.13x memory usage +178.97 MB
47+
48+
**All measurements for memory usage were the same**

0 commit comments

Comments
 (0)