由于 UNIQUE KEY,您已经在 users.email 上建立了索引。这将针对您的电子邮件条件优化行选择。
主键users.id 隐含地是索引的一部分,这将用于在posts 中查找匹配的行。
然后您需要在posts 上建立一个索引,以便每个users.id 可以有效地定位匹配的行。索引还应该在created_at 上为范围条件提供第二列。
ALTER TABLE posts ADD INDEX (user_id, created_at);
您可以看到这如何影响 EXPLAIN 并看到使用了索引。
新索引之前:
+----+-------------+-------+------------+-------+---------------+-------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+-------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | users | NULL | const | PRIMARY,email | email | 1022 | const | 1 | 100.00 | Using index |
| 1 | SIMPLE | posts | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
+----+-------------+-------+------------+-------+---------------+-------+---------+-------+------+----------+-------------+
posts 上的连接将被强制执行表扫描。
新索引之后:
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+
| 1 | SIMPLE | users | NULL | const | PRIMARY,email | email | 1022 | const | 1 | 100.00 | Using index |
| 1 | SIMPLE | posts | NULL | range | user_id | user_id | 8 | NULL | 1 | 100.00 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+-------+------+----------+--------------------------+
与posts 的连接使用索引。
您可能会喜欢我的演示文稿How to Design Indexes, Really,或者我的演示文稿video。