I am trying to find a chain of exactly 2^1024 lenght, here is a simplified version:
CREATE VIEW full2 AS SELECT a.id1,b.id2 FROM gt a JOIN gt b ON a.id2=b.id1;
CREATE VIEW full3 AS SELECT a.id1,b.id2 FROM full2 a JOIN full2 b ON a.id2=b.id1;
CREATE VIEW full4 AS SELECT a.id1,b.id2 FROM full3 a JOIN full3 b ON a.id2=b.id1;
The problem is that a lot of rows die out after after f2
, but somehow mysql's execution plan is
+----+-------------+-------+------------+-------+---------------+------+---------+--------------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+------+---------+--------------+------+----------+--------------------------+
| 1 | SIMPLE | gt1 | NULL | index | id1,id2 | id2 | 4 | NULL | 33 | 81.00 | Using where; Using index |
| 1 | SIMPLE | gt2 | NULL | ref | id1,id2 | id2 | 4 | picr.gt1.id1 | 1 | 90.00 | Using where; Using index |
| 1 | SIMPLE | gt2 | NULL | ref | id1,id2 | id1 | 4 | picr.gt1.id2 | 1 | 90.00 | Using where; Using index |
| 1 | SIMPLE | gt1 | NULL | ref | id1,id2 | id2 | 4 | picr.gt2.id1 | 1 | 90.00 | Using where; Using index |
| 1 | SIMPLE | gt1 | NULL | ref | id1,id2 | id1 | 4 | picr.gt2.id2 | 1 | 90.00 | Using where; Using index |
| 1 | SIMPLE | gt2 | NULL | ref | id1,id2 | id2 | 4 | picr.gt1.id1 | 1 | 90.00 | Using where; Using index |
| 1 | SIMPLE | gt2 | NULL | ref | id1 | id1 | 4 | picr.gt1.id2 | 1 | 100.00 | Using index |
| 1 | SIMPLE | gt1 | NULL | ref | id2 | id2 | 4 | picr.gt2.id1 | 1 | 100.00 | Using index |
+----+-------------+-------+------------+-------+---------------+------+---------+--------------+------+----------+--------------------------+
Which I should explain:
for each row in comparison1 that id2 MIGHT exist in comparison.id1
for each row in comparison2 that id2 MIGHT exist in comparison.id1 and id1 MIGHT exist in comparison.id2
for each row in comparison3 that id2 MIGHT exist in comparison.id1 and id1 MIGHT exist in comparison.id2
...
does comparison1.id2=comparison2.id1 and comparison2.id2=comparison3.id1 comparison3.id2=comparison4.id1 ...
...
}
}
}
This is a huge drain on query time. This is because I actually don't have any rows in f2(not yet anyway) and if nothing is in f2 then joining f2 (nothing) to actually any other query should immediately stop the sql calculation(yet it might start right to left, but same problem, right side will also be empty). Calculation time rises exponentially on each new view.
How can I do something like this?
for each row in comparison1
for each row in comparison2 that id1 exists in comparison1 .id2
if fail then skip
for each row in comparison3 that id1 exists in comparison2 .id2
if fail then skip
...
does comparison1.id2=comparison2.id1 and comparison2.id2=comparison3.id1 comparison3.id2=comparison4.id1 ...
...
}
}
}
It is not possible? Yes it is! This is a more weird query, won't go into details(it was supposed to join everything from lenght 1 to 1024 without any unions and saves id1,id2 and previous id2 and has huge where condition) but in essence it does more and faster!
mysql> describe select * from part4_v2_3colleftjoin;
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------------+
| 1 | SIMPLE | p | NULL | index | NULL | id2 | 4 | NULL | 33 | 100.00 | Using index |
| 1 | SIMPLE | f | NULL | ALL | id1,id2 | NULL | NULL | NULL | 33 | 100.00 | Range checked for each record (index map: 0x3) |
| 1 | SIMPLE | p | NULL | ALL | id1,id2 | NULL | NULL | NULL | 33 | 100.00 | Range checked for each record (index map: 0x3) |
| 1 | SIMPLE | f | NULL | ALL | id1,id2 | NULL | NULL | NULL | 33 | 100.00 | Range checked for each record (index map: 0x3) |
| 1 | SIMPLE | p | NULL | index | id1 | id2 | 4 | NULL | 33 | 100.00 | Using where; Using index |
| 1 | SIMPLE | f | NULL | ALL | id1,id2 | NULL | NULL | NULL | 33 | 100.00 | Range checked for each record (index map: 0x3) |
| 1 | SIMPLE | p | NULL | ALL | id1,id2 | NULL | NULL | NULL | 33 | 100.00 | Range checked for each record (index map: 0x3) |
| 1 | SIMPLE | f | NULL | ALL | id1,id2 | NULL | NULL | NULL | 33 | 100.00 | Range checked for each record (index map: 0x3) |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+------------------------------------------------+