面试题答案
一键面试索引使用优化
- 创建合适的索引
- 对于连接条件,在连接字段上创建索引。例如在
JOIN
子句中使用的ON
条件涉及的字段,如table1.column1 = table2.column2
,在table1.column1
和table2.column2
上创建索引。这能加快连接时数据匹配的速度,减少全表扫描。 - 复合索引的使用。如果连接条件涉及多个字段,比如
table1.column1 = table2.column1 AND table1.column2 = table2.column2
,可以考虑创建复合索引(column1, column2)
,但要注意复合索引字段顺序,一般将选择性高(重复值少)的字段放在前面。
- 对于连接条件,在连接字段上创建索引。例如在
- 避免索引失效
- 连接条件中避免对索引字段进行函数操作。例如不要写成
table1. column1 + 1 = table2.column1
,这会导致索引失效,而应尽量通过调整数据逻辑避免这种写法。 - 字符串类型字段连接时,确保两边类型一致且不要在连接条件中使用
LIKE '%value'
这种会导致索引失效的写法,若必须使用模糊匹配,可考虑使用LIKE 'value%'
并结合全文索引(在合适场景下)。
- 连接条件中避免对索引字段进行函数操作。例如不要写成
表连接顺序优化
- 小表驱动大表
- 在
Nest - Loop JOIN
(嵌套循环连接)场景下,将数据量小的表放在JOIN
操作的左边(驱动表)。因为MySQL在执行JOIN
操作时,一般会先读取驱动表的数据,然后根据驱动表的数据去匹配被驱动表的数据。如果驱动表数据量小,整体扫描次数会减少,从而提升性能。例如有表small_table
(100条记录)和big_table
(10000条记录),应该写成SELECT * FROM small_table JOIN big_table ON small_table.id = big_table.small_table_id;
- 在
- 使用
STRAIGHT_JOIN
强制连接顺序- 当优化器选择的连接顺序不是最优时,可以使用
STRAIGHT_JOIN
关键字来强制按照查询语句中表的顺序进行连接。例如SELECT STRAIGHT_JOIN * FROM table1 JOIN table2 ON table1.id = table2.table1_id;
这就会让table1
作为驱动表先进行处理,若根据经验或实际测试知道这种顺序性能更好,就可以采用此方法。
- 当优化器选择的连接顺序不是最优时,可以使用
其他优化手段
- JOIN类型选择
- 了解不同
JOIN
类型的性能特点。例如INNER JOIN
一般性能较好,因为它只返回满足连接条件的行。而LEFT JOIN
可能会产生更多的数据(左表所有行都会返回,即使右表没有匹配行),如果不需要左表所有行都显示,应优先使用INNER JOIN
。 - 在某些情况下,
HASH JOIN
可能比Nest - Loop JOIN
更高效,特别是在大数据量且数据分布均匀时。MySQL优化器会根据表大小、索引等情况选择合适的JOIN
算法,但有时也可通过提示来影响优化器的选择(不过不同版本支持情况有差异)。
- 了解不同
- 减少返回字段
- 只选择需要的字段,避免使用
SELECT *
。减少返回的数据量不仅能减少网络传输开销,还能在一定程度上提升查询性能,因为数据库不需要读取和处理多余的字段数据。例如SELECT column1, column2 FROM table1 JOIN table2 ON table1.id = table2.table1_id;
- 只选择需要的字段,避免使用