Summary
Query runs 4 operators; returns 75 rows in 0.18 ms. No warnings.
- Total time
- 178 µs
- Rows returned
- 75
- Rows examined
- 75
- Operators
- 4
SQL
select testdb.t1.id AS id,testdb.t1.a AS a,testdb.t1.b AS b,testdb.t1.c AS c,testdb.t1.d AS d
from testdb.t1
where ((testdb.t1.a = 50) or (testdb.t1.b = 100))
Execution plan (flamegraph)
Click a plan operator to inspect details.
myteach — interactive algorithm catalog
Every operator shown above has a hands-on lesson with a cost-model slider and an animated walk-through. The catalog is the central index — bookmark it once, revisit per query:
Lessons relevant to this plan
Raw sidecar (JSON)
{
"$schema": "https://myflames.dev/schemas/sidecar-v1.json",
"schema_version": "1.3",
"generated_at": "2026-04-25T12:51:28Z",
"myflames_version": "1.5.0",
"source": {
"type": "file"
},
"plan_summary": {
"total_time_ms": 0.178,
"rows_sent": 75,
"rows_examined_estimate": 75,
"operator_count": 4,
"max_depth": 3
},
"optimizer_switches": [
{
"name": "index_merge",
"value": "on",
"explanation": "Uses two or more index range scans on the same table and combines row IDs (union/intersection/sort_union) instead of falling back to a full scan. A composite index is usually faster.",
"node_labels": [
"Deduplicate rows sorted by row ID"
]
},
{
"name": "index_merge_union",
"value": "on",
"explanation": "Union variant of index_merge: OR'ed predicates are satisfied by scanning each index separately, then UNION'ing their row IDs.",
"node_labels": [
"Deduplicate rows sorted by row ID"
]
}
],
"warnings": [],
"suggestions": [],
"executive_summary": "Query runs 4 operators; returns 75 rows in 0.18 ms. No warnings.",
"plan_tree": {
"node_id": "n:4bc09dd3516c",
"short_label": "Filter: (((t1.a = 50) or (t1.b = 100)))",
"folded_label": "FILTER (((t1.a = 50) or (t1.b = 100))) starts=1 rows=75",
"children": [
{
"node_id": "n:f85ded12d5b5",
"short_label": "Deduplicate rows sorted by row ID",
"folded_label": "Deduplicate rows sorted by row ID starts=1 rows=75",
"children": [
{
"node_id": "n:395d4e419799",
"short_label": "Index range scan [t1.idx_a]",
"folded_label": "INDEX RANGE SCAN [t1.idx_a] starts=1 rows=50",
"children": []
},
{
"node_id": "n:3b024c1dd920",
"short_label": "Index range scan [t1.idx_b]",
"folded_label": "INDEX RANGE SCAN [t1.idx_b] starts=1 rows=25",
"children": []
}
]
}
]
},
"query": {
"raw": "/* select#1 */ select `testdb`.`t1`.`id` AS `id`,`testdb`.`t1`.`a` AS `a`,`testdb`.`t1`.`b` AS `b`,`testdb`.`t1`.`c` AS `c`,`testdb`.`t1`.`d` AS `d` from `testdb`.`t1` where ((`testdb`.`t1`.`a` = 50) or (`testdb`.`t1`.`b` = 100))",
"beautified": "select testdb.t1.id AS id,testdb.t1.a AS a,testdb.t1.b AS b,testdb.t1.c AS c,testdb.t1.d AS d\nfrom testdb.t1\nwhere ((testdb.t1.a = 50) or (testdb.t1.b = 100))"
},
"teach_hooks": [
{
"lesson": "filter",
"match": {
"folded_label": "FILTER (((t1.a = 50) or (t1.b = 100))) starts=1 rows=75",
"short_label": "Filter: (((t1.a = 50) or (t1.b = 100)))"
},
"controls": {
"input_rows": 75,
"selectivity": 10.0
},
"note": "Filter: ((t1.a = 50) or (t1.b = 100))",
"query_sql": "/* select#1 */ select `testdb`.`t1`.`id` AS `id`,`testdb`.`t1`.`a` AS `a`,`testdb`.`t1`.`b` AS `b`,`testdb`.`t1`.`c` AS `c`,`testdb`.`t1`.`d` AS `d` from `testdb`.`t1` where ((`testdb`.`t1`.`a` = 50) or (`testdb`.`t1`.`b` = 100))"
},
{
"lesson": "non_unique_lookup",
"match": {
"folded_label": "INDEX RANGE SCAN [t1.idx_a] starts=1 rows=50",
"short_label": "Index range scan [t1.idx_a]"
},
"controls": {
"rows": 50,
"selectivity": 40.0,
"covering": false
},
"note": "Index range scan on t1 using idx_a over (a = 50) (t1)",
"query_sql": "/* select#1 */ select `testdb`.`t1`.`id` AS `id`,`testdb`.`t1`.`a` AS `a`,`testdb`.`t1`.`b` AS `b`,`testdb`.`t1`.`c` AS `c`,`testdb`.`t1`.`d` AS `d` from `testdb`.`t1` where ((`testdb`.`t1`.`a` = 50) or (`testdb`.`t1`.`b` = 100))"
},
{
"lesson": "non_unique_lookup",
"match": {
"folded_label": "INDEX RANGE SCAN [t1.idx_b] starts=1 rows=25",
"short_label": "Index range scan [t1.idx_b]"
},
"controls": {
"rows": 25,
"selectivity": 40.0,
"covering": false
},
"note": "Index range scan on t1 using idx_b over (b = 100) (t1)",
"query_sql": "/* select#1 */ select `testdb`.`t1`.`id` AS `id`,`testdb`.`t1`.`a` AS `a`,`testdb`.`t1`.`b` AS `b`,`testdb`.`t1`.`c` AS `c`,`testdb`.`t1`.`d` AS `d` from `testdb`.`t1` where ((`testdb`.`t1`.`a` = 50) or (`testdb`.`t1`.`b` = 100))"
}
],
"operator_complexities": [
{
"node_id": "n:f85ded12d5b5",
"folded_label": "Deduplicate rows sorted by row ID starts=1 rows=75",
"short_label": "Deduplicate rows sorted by row ID",
"complexity": {
"big_o": "O(Σ kᵢ)",
"short": "Σ kᵢ",
"severity": "medium",
"rationale": "Index merge (union): each index scan returns kᵢ row IDs; merging them through a sorted-list union costs a pass over the total.",
"confidence": "typical",
"learn_more": "index_merge"
}
},
{
"node_id": "n:395d4e419799",
"folded_label": "INDEX RANGE SCAN [t1.idx_a] starts=1 rows=50",
"short_label": "Index range scan [t1.idx_a]",
"complexity": {
"big_o": "O(log n + k)",
"short": "log n + k",
"severity": "good",
"rationale": "Index range scan: one B+tree descent to the range start, then a sequential walk over k matching index entries.",
"confidence": "exact",
"learn_more": "index_range_scan"
}
},
{
"node_id": "n:3b024c1dd920",
"folded_label": "INDEX RANGE SCAN [t1.idx_b] starts=1 rows=25",
"short_label": "Index range scan [t1.idx_b]",
"complexity": {
"big_o": "O(log n + k)",
"short": "log n + k",
"severity": "good",
"rationale": "Index range scan: one B+tree descent to the range start, then a sequential walk over k matching index entries.",
"confidence": "exact",
"learn_more": "index_range_scan"
}
}
]
}