I am trying to perform joins between two temporary tables, creating an index on the join key for each temp table. However, when I EXPLAIN
the join, the row estimates always seem to come out vastly incorrect - the first table will have roughly the correct number, but the second table always returns rows=1
. Upon digging further, it seems that MySQL hasn't properly done any key distribution analysis on the created indexes. SHOW INDEX
returns the total number of rows, not the number of unique keys. Only after I force an ANALYZE TABLE
on both tables, all the numbers are much more representative of the data.
Interestingly, this whole ordeal doesn't occur with regular, non-temporary tables. After creating the indexes, SHOW INDEX
and EXPLAIN
both return reasonable numbers immediately.
Is there a reason this is happening? For now, I will move forward with the calls to ANALYZE TABLE
, as getting an accurate estimate of rows is important for my use case, and it doesn't seem to have much added overhead. However, it would be nice to know why this is happening, and if there are any oversights to the approach I'm taking.
EDIT: Here's an example of the problem I'm describing:
I've created an example table as such:
CREATE TEMPORARY TABLE t1 (
id INT PRIMARY KEY,
name VARCHAR(50),
age INT
);
And inserted records with 5 unique names, of which there are ~20 records per name. I then copy these values over into an identical (temporary) t2
.
I then create indexes on both t1
and t2
(on the single column name
), and run the following EXPLAIN
:
mysql> EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.name = t2.name;
+----+-------------+-------+------------+------+---------------+------+---------+--------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+--------------+------+----------+-------------+
| 1 | SIMPLE | t1 | NULL | ALL | i1 | NULL | NULL | NULL | 100 | 100.00 | Using where |
| 1 | SIMPLE | t2 | NULL | ref | i2 | i2 | 203 | test.t1.name | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+--------------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)
Note the row estimate for t2
is only 1, whereas after I run ANALYZE TABLE t1, t2;
I get the following EXPLAIN
:
mysql> explain select * from t1 use index(i) join t2 use index(i) on t1.name=t2.name;
+----+-------------+-------+------------+------+---------------+------+---------+--------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+--------------+------+----------+-------------+
| 1 | SIMPLE | t1 | NULL | ALL | i1 | NULL | NULL | NULL | 100 | 100.00 | Using where |
| 1 | SIMPLE | t2 | NULL | ref | i2 | i2 | 203 | test.t1.name | 20 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+--------------+------+----------+-------------+
The row estimates become 100 for t1
and 20 for t2
, which is much more accurate. If I create the tables as non-temporary though, the ANALYZE TABLE
step is not necessary to get the more accurate estimates.
CREATE TABLEs
and the query andEXPLAIN SELECT ...
. I think I can explain what you are seeing, but I need those details to be sure.EXPLAIN
says that there is aKEY(name)
calledi2
ont2
. At that point, "1" is a reasonable value.EXPLAIN
is using the index, but I'm wondering about the distinction between key distribution analyses performed on temporary tables vs. normal tables upon index creation.