面试题答案
一键面试开启慢查询日志
- 修改配置文件:
- 对于大多数Linux系统,MySQL配置文件通常是
/etc/my.cnf
或/etc/mysql/my.cnf
。打开该文件,在[mysqld]
部分添加或修改以下配置:slow_query_log = 1 long_query_time = 2 # 执行时间超过2秒的SQL会被记录,可按需调整 slow_query_log_file = /var/log/mysql/slow - query.log # 日志文件路径,可自定义
- 修改完成后,重启MySQL服务使配置生效,例如在Ubuntu系统上执行
sudo systemctl restart mysql
。
- 对于大多数Linux系统,MySQL配置文件通常是
- 使用SET语句(临时生效):
- 可以在MySQL客户端中使用以下命令临时开启慢查询日志:
SET GLOBAL slow_query_log = 1; SET GLOBAL long_query_time = 2;
- 这种方式只在当前MySQL会话有效,MySQL重启后配置会失效。
- 可以在MySQL客户端中使用以下命令临时开启慢查询日志:
常见查询性能慢的原因
- 没有使用索引:
- 当SQL语句没有利用合适的索引时,数据库需要全表扫描来获取数据,这会导致查询性能急剧下降。例如,在
SELECT * FROM users WHERE username = 'test';
语句中,如果username
字段没有索引,MySQL就需要逐行匹配数据。
- 当SQL语句没有利用合适的索引时,数据库需要全表扫描来获取数据,这会导致查询性能急剧下降。例如,在
- 索引设计不合理:
- 即使存在索引,但如果索引设计不合理也无法发挥其应有的作用。比如复合索引的顺序不正确,或者索引列选择性低(大量重复值),都会影响查询性能。
- 数据量过大:
- 表中的数据量巨大时,即使有索引,某些复杂查询仍然可能很慢。例如对一个包含百万条记录的表进行全表扫描或复杂的关联查询。
- 复杂的SQL语句:
- 例如多层嵌套的子查询、复杂的JOIN操作等,这些复杂的逻辑会增加数据库的计算负担,导致查询性能下降。
基础调优方法
- 优化索引:
- 添加合适的索引:通过分析SQL语句和业务需求,为经常作为查询条件的字段添加索引。例如对于
SELECT * FROM orders WHERE order_date > '2023 - 01 - 01';
,可以在order_date
字段上添加索引。 - 优化复合索引:确保复合索引的列顺序与查询条件中的顺序相匹配,以提高索引的利用率。比如
SELECT * FROM products WHERE category = 'electronics' AND price > 100;
,复合索引应先包含category
列,再包含price
列。
- 添加合适的索引:通过分析SQL语句和业务需求,为经常作为查询条件的字段添加索引。例如对于
- 优化SQL语句:
- 避免子查询嵌套:将子查询改写为JOIN操作,以减少数据库的处理复杂度。例如,将
SELECT * FROM orders WHERE customer_id IN (SELECT customer_id FROM customers WHERE region = 'Asia');
改写为SELECT orders.* FROM orders JOIN customers ON orders.customer_id = customers.customer_id WHERE customers.region = 'Asia';
- 简化复杂JOIN:检查JOIN条件是否必要,尽量减少不必要的JOIN操作。同时,确保JOIN操作使用的字段上有合适的索引。
- 避免子查询嵌套:将子查询改写为JOIN操作,以减少数据库的处理复杂度。例如,将
- 分表:
- 水平分表:当数据量过大时,按一定规则(如时间、ID范围等)将数据分散到多个表中。例如,将订单表按年份水平分割为
orders_2022
、orders_2023
等表,查询特定年份的数据时只需查询对应的表,减少单次查询的数据量。 - 垂直分表:根据字段的使用频率和相关性,将表中的字段拆分到不同的表中。例如,将用户表中不常用的详细信息字段(如个人简介、备注等)拆分到另一个表,主用户表只保留常用字段,提高查询常用信息的性能。
- 水平分表:当数据量过大时,按一定规则(如时间、ID范围等)将数据分散到多个表中。例如,将订单表按年份水平分割为