pingcap/tidb

some OR condition can be pushed down to the leaves of the JOIN

Open

#35.261 geöffnet am 9. Juni 2022

Auf GitHub ansehen
 (3 Kommentare) (0 Reaktionen) (2 zugewiesene Personen)Go (6.186 Forks)batch import
help wantedsig/plannertype/enhancement

Repository-Metriken

Stars
 (40.090 Stars)
PR-Merge-Metriken
 (Durchschn. Merge 14T 4h) (346 gemergte PRs in 30 T)

Beschreibung

Enhancement

Consider the following SQL

explain select * from t join t1 on t.id = t1.id join t2 on t.id = t2.id where t.b = 1 or t1.a = 2 or t2.b = 3;
mysql> explain select * from t join t1 on t.id = t1.id join t2 on t.id = t2.id where t.b = 1 or t1.a = 2 or t2.b = 3;
+-------------------------------+----------+-----------+---------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| id                            | estRows  | task      | access object | operator info                                                                                                                                  |
+-------------------------------+----------+-----------+---------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| HashJoin_24                   | 15625.00 | root      |               | inner join, equal:[eq(jingyocar.t.id, jingyocar.t2.id)], other cond:or(eq(jingyocar.t.b, 1), or(eq(jingyocar.t1.a, 2), eq(jingyocar.t2.b, 3))) |
| ├─TableReader_68(Build)       | 10000.00 | root      |               | data:TableFullScan_67                                                                                                                          |
| │ └─TableFullScan_67          | 10000.00 | cop[tikv] | table:t2      | keep order:false, stats:pseudo                                                                                                                 |
| └─MergeJoin_42(Probe)         | 12500.00 | root      |               | inner join, left key:jingyocar.t.id, right key:jingyocar.t1.id                                                                               |
|   ├─TableReader_39(Build)     | 10000.00 | root      |               | data:TableFullScan_38                                                                                                                          |
|   │ └─TableFullScan_38        | 10000.00 | cop[tikv] | table:t1      | keep order:true, stats:pseudo                                                                                                                  |
|   └─TableReader_37(Probe)     | 10000.00 | root      |               | data:TableFullScan_36                                                                                                                          |
|     └─TableFullScan_36        | 10000.00 | cop[tikv] | table:t       | keep order:true, stats:pseudo                                                                                                                  |
+-------------------------------+----------+-----------+---------------+------------------------------------------------------------------------------------------------------------------------------------------------+

As you can see, in the current execution plan, the OR condition is blocked at the top of the join node. But actually, if we push the OR condition into the table t side, the condition can actually be transformed to t.b = 1 or false or false => t.b = 1. If we push it to the t1 side, we get false or t1.a = 2 or false => t1.a = 2. If we push it to the t2 side, we get false or false or t2.b=3 => t2.b=3. This indicates that we can split the OR condition and push each part to the place where need it.

Contributor Guide