I have a query which includes a join and I have an index on the tables:
SELECT e.entry, e.user_id from entries e left join users u on
e.user_id=u.user_id where e.tenant_id=? AND u.active=1 AND e.valid=1
The user table has ~116k rows and the entries table has 165k rows and the above query takes ~60 seconds to run. Server is 8 core, 32GB RAM with SSD disks so I don't imagine this is normal.
I have ran explain against the query and it comes back with:
+----+-------------+-------+-------+---------------+------------+---------+-------+--------+-----------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------------+---------+-------+--------+-----------------------------------------------------------------+
| 1 | SIMPLE | e | ref | tenant_id | tenant_id | 4 | const | 3589 | Using where |
| 1 | SIMPLE | u | index | NULL | tenant_id | 314 | NULL | 116710 | Using where; Using index; Using join buffer (Block Nested Loop) |
+----+-------------+-------+-------+---------------+------------+---------+-------+--------+-----------------------------------------------------------------+
The index on users is:
+---------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| users | 0 | PRIMARY | 1 | id | A | 116710 | NULL | NULL | | BTREE | | |
| users | 1 | tenant_id | 1 | tenant_id | A | 19451 | NULL | NULL | | BTREE | | |
| users | 1 | tenant_id | 2 | user_id | A | 116710 | NULL | NULL | | BTREE | | |
| users | 1 | tenant_id | 3 | group_id | A | 116710 | NULL | NULL | | BTREE | | |
| users | 1 | tenant_id | 4 | valid | A | 116710 | NULL | NULL | | BTREE | | |
+---------------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
I struggle to get my head around indexes especially with joins but it looks like the index on users is not being used on the query as it is scanning all 116k rows - is that correct?
If so, how can I setup the index to improve the performance and not have to scan all 116k rows?
SHOW CREATE TABLE tablename;
output. For both tables.u.tenant_id
in your query (by join or constant), but your only index onusers
starts withtenant_id
so it cannot be used effectively and is instead scanned in its entirety. You either need to join ontenant_id
too or add a different index (or modify the current one) if such join is not what you need.