面试题答案
一键面试索引优化
- 添加合适索引:
- 分析慢查询语句中的
WHERE
条件,对频繁用于过滤的字段添加索引。例如,如果查询为SELECT * FROM users WHERE age > 30 AND city = 'Beijing';
,可以考虑在age
和city
字段上添加复合索引CREATE INDEX idx_age_city ON users(age, city);
,这样能加快数据的定位速度。 - 对于连接查询,在连接字段上添加索引。比如
SELECT * FROM orders JOIN customers ON orders.customer_id = customers.id;
,在orders.customer_id
和customers.id
上添加索引能提升连接效率。
- 分析慢查询语句中的
- 删除无用索引:定期检查数据库中的索引,删除那些从未被使用或者很少被使用的索引。过多的索引会增加数据插入、更新和删除操作的开销,因为每次数据变动时,MySQL 都需要更新相应的索引。
查询语句改写
- 避免全表扫描:
- 尽量避免在
WHERE
条件中使用函数操作。例如,SELECT * FROM users WHERE UPPER(name) = 'JOHN';
会导致全表扫描,应改为SELECT * FROM users WHERE name = 'john';
并在name
字段上添加合适索引。 - 避免使用
LIKE '%xxx'
,因为这种方式无法利用索引,如SELECT * FROM products WHERE product_name LIKE '%book';
,如果必须使用LIKE
,可以改为LIKE 'book%'
并在product_name
字段添加索引。
- 尽量避免在
- 优化子查询:
- 对于一些子查询,可以改写为连接查询。例如子查询
SELECT * FROM orders WHERE customer_id IN (SELECT id FROM customers WHERE country = 'USA');
可以改写为连接查询SELECT orders.* FROM orders JOIN customers ON orders.customer_id = customers.id AND customers.country = 'USA';
,连接查询通常性能更好。
- 对于一些子查询,可以改写为连接查询。例如子查询
- 分页优化:
- 大数据量分页时,使用
LIMIT OFFSET
会随着OFFSET
增大性能急剧下降。例如SELECT * FROM articles LIMIT 100000, 10;
,可以通过记录上次查询的最大 ID 来优化,如SELECT * FROM articles WHERE id > (SELECT id FROM articles ORDER BY id LIMIT 100000, 1) LIMIT 10;
- 大数据量分页时,使用
数据库配置优化
- 调整缓存参数:
- 增加
innodb_buffer_pool_size
,它用于缓存 InnoDB 表的数据和索引。更大的缓冲池能让更多的数据和索引缓存在内存中,减少磁盘 I/O。例如,可以根据服务器内存情况适当增大该值,一般建议设置为服务器物理内存的 60% - 80%。 - 调整
key_buffer_size
(适用于 MyISAM 存储引擎),它缓存 MyISAM 表的索引块,合理设置能提高 MyISAM 表的查询性能。
- 增加
- 优化线程参数:
- 调整
max_connections
,它设置了 MySQL 允许的最大连接数。如果设置过大,可能会导致系统资源耗尽;设置过小,会限制同时连接的用户数。根据服务器性能和实际业务需求合理调整该值。 - 优化
thread_cache_size
,它缓存空闲线程,减少线程创建和销毁的开销。适当增大该值可以提高高并发场景下的性能。
- 调整