SELECT COALESCE(tb2.numero_novo, tb1.numero_original) as numero
FROM
tb1
LEFT JOIN tb2 ON tb2.id = tb1.id
WHERE
tb1.numero_original = <PARAM> OR tb2.numero_novo = <PARAM>
The above query generates a full table scan. How to optimize this query?
EXPLAIN:
+----+-------------+-------+-------+----------------+----------------+---------+------+----------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+----------------+----------------+---------+------+----------+----------------------------------------------------+
| 1 | SIMPLE | tb1 | index | numero_original| numero_original| 5 | NULL | 11683843 | Using index |
| 1 | SIMPLE | tb2 | ALL | PRIMARY | NULL | NULL | NULL | 2 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+-------+----------------+----------------+---------+------+----------+----------------------------------------------------+
The problem I need to solve is:
tb1
is a table that contains the numero_original
field. I want to create the tb2
table to store a new value for this field, (which I called numero_novo
). I did this because I can not change the value of the numero_original
field, and I would not like to create the numero_novo
field in the tb1
table, since it would be NULL in more than 95% of the 11 million records table. >
EDIT:
As they talked about indexes, I'm putting more information:
-
tb1
has as its primary key theid
field; - The
numero_original
field of thetb1
table has index; -
tb2
has as its primary key the fieldstb1_id
andnumero_novo
; - The
tb1
table has 11mi + records; - The newly created
tb2
table has 2 test records.
.
mysql> show indexes from tb1;
+-------+------------+-------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tb1 | 0 | PRIMARY | 1 | id | A | 11066164 | NULL | NULL | | BTREE | | |
| tb1 | 1 | numero_original | 1 | numero_original | A | 5533082 | NULL | NULL | YES | BTREE | | |
+-------+------------+-------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
mysql> show indexes from tb2;
+-------+------------+------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tb2 | 0 | PRIMARY | 1 | tb1_id | A | 2 | NULL | NULL | | BTREE | | |
| tb2 | 0 | PRIMARY | 2 | numero_novo | A | 2 | NULL | NULL | | BTREE | | |
+-------+------------+------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
EXPLAIN selecting with WHERE only in the first table ( tb1
):
+----+-------------+-------+------+----------------+----------------+---------+-------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+----------------+----------------+---------+-------+------+----------------------------------------------------+
| 1 | SIMPLE | tb1 | ref | numero_original| numero_original| 5 | const | 4 | Using index |
| 1 | SIMPLE | tb2 | ALL | PRIMARY | NULL | NULL | NULL | 2 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------+----------------+----------------+---------+-------+------+----------------------------------------------------+
EXPLAIN selecting with WHERE only in the second table ( tb2
):
+----+-------------+-------+--------+---------------+---------+---------+-------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+---------------+---------+---------+-------------------------+------+-------------+
| 1 | SIMPLE | tb2 | ALL | PRIMARY | NULL | NULL | NULL | 2 | Using where |
| 1 | SIMPLE | tb1 | eq_ref | PRIMARY | PRIMARY | 4 | sistema.tb2.tb1_id | 1 | NULL |
+----+-------------+-------+--------+---------------+---------+---------+-------------------------+------+-------------+