Query is 1.76x slower in Dolt than MySQL
- Dominant language
- Go
- Stars
- 24.4k
- Forks
- 873
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 108
Description
## Summary
Dolt median latency is 1.76x MySQL
MySQL 8.4.11 median: **3.854 ms**
Dolt 2.3.1 median: **6.786 ms**
Dolt/MySQL ratio: **1.76x**
## Reproduction
Standalone reproduction: [repro.sql](https://gist.github.com/fulghum/c85c813ec8f308ff62cc06dfd484a0dc)
The generated script is standalone and creates `querylab_repro_25804b89a803b42a`, loads 3500 deterministic rows, analyzes the retained tables, and runs the query. It preserves all rows and indexes for tables referenced by the query; unrelated tables were removed.
```sql
WITH item_totals AS (SELECT order_id, SUM(quantity * unit_price) computed_total FROM order_items GROUP BY order_id), mismatches AS (SELECT o.id, o.customer_id, o.total, i.computed_total FROM orders o JOIN item_totals i ON i.order_id=o.id WHERE ABS(o.total-i.computed_total)>100) SELECT c.region, COUNT(*) mismatch_count FROM mismatches m JOIN customers c ON c.id=m.customer_id GROUP BY c.region ORDER BY mismatch_count DESC, c.region
```
## Plan difference summary
- Join strategy differs: MySQL 8.4.11 uses nested-loop join; Dolt 2.3.1 uses index lookup join.
- Join input order differs: MySQL 8.4.11 accesses temporary → i → o → c; Dolt 2.3.1 accesses orders → customers.
- Scan targets differ: MySQL 8.4.11 scans temporary, i; Dolt 2.3.1 scans order_items.
- Index choices differ: MySQL 8.4.11 uses idx_items_order, PRIMARY, PRIMARY; Dolt 2.3.1 uses orders.id, customers.id.
- Aggregation strategy differs: MySQL 8.4.11 materializes an intermediate result; Dolt 2.3.1 does not show materialization.
MySQL 8.4.11 explain plan
```text
-> Sort: mismatch_count DESC, c.region
-> Table scan on
-> Aggregate using temporary table
-> Nested loop inner join (cost=1674 rows=860)
-> Nested loop inner join (cost=1088 rows=860)
-> Table scan on i (cost=488..502 rows=860)
-> Materialize CTE item_totals (cost=488..488 rows=860)
-> Group aggregate: sum((order_items.quantity * order_items.unit_price)) (cost=402 rows=860)
-> Index scan on order_items using idx_items_order (cost=202 rows=2000)
-> Filter: (abs((o.total - i.computed_total)) > 100) (cost=0.25 rows=1)
-> Single-row index lookup on o using PRIMARY (id=i.order_id) (cost=0.25 rows=1)
-> Single-row index lookup on c using PRIMARY (id=o.customer_id) (cost=0.25 rows=1)
```
Dolt 2.3.1 explain plan
```text
Project
├─ columns: [c.region, count(1) as mismatch_count]
└─ Sort(mismatch_count DESC, c.region ASC)
└─ Project
├─ columns: [count(1), c.region, count(1) as mismatch_count]
└─ GroupBy
├─ select: COUNT(1), c.region
├─ group: c.region
└─ LookupJoin
├─ SubqueryAlias
│ ├─ name: m
│ ├─ outerVisibility: false
│ ├─ isLateral: false
│ ├─ cacheable: true
│ ├─ colSet: (21-24)
│ ├─ tableId: 8
│ └─ Project
│ ├─ columns: [o.id, o.customer_id, o.total, i.computed_total]
│ └─ Filter
│ ├─ (abs((o.total - i.computed_total)) > 100)
│ └─ LookupJoin
│ ├─ SubqueryAlias
│ │ ├─ name: i
│ │ ├─ outerVisibility: false
│ │ ├─ isLateral: false
│ │ ├─ cacheable: true
│ │ ├─ colSet: (15,16)
│ │ ├─ tableId: 5
│ │ └─ Project
│ │ ├─ columns: [order_items.order_id, sum((order_items.quantity * order_items.unit_price)) as computed_total]
│ │ └─ GroupBy
│ │ ├─ select: SUM((order_items.quantity * order_items.unit_price)), order_items.order_id
│ │ ├─ group: order_items.order_id
│ │ └─ Table
│ │ ├─ name: order_items
│ │ └─ columns: [order_id quantity unit_price]
│ └─ TableAlias(o)
│ └─ IndexedTableAccess(orders)
│ ├─ index: [orders.id]
│ ├─ columns: [id customer_id total]
│ └─ keys: i.order_id
└─ TableAlias(c)
└─ IndexedTableAccess(customers)
├─ index: [customers.id]
├─ columns: [id region]
└─ keys: m.customer_id
```
QueryLab finding: `25804b89a803b42a`
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by running the standalone repro.sql script and comparing Dolt 2.3.1 with MySQL 8.4.11 using the reported query and execution plans. Investigate the query-planning differences listed in the issue, then rerun the benchmark to confirm that the reported Dolt slowdown is resolved.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, mysql, sql
- Domain
- databases, performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100