面试题答案
一键面试SQL语句
SELECT
o.user_id,
SUM(p.price * oi.quantity) AS total_price
FROM
orders o
JOIN
order_items oi ON o.order_id = oi.order_id
JOIN
products p ON oi.product_id = p.product_id
GROUP BY
o.user_id
ORDER BY
total_price DESC
LIMIT 10;
MySQL数据访问策略优化手段
- 索引优化:
- 在
orders
表的order_id
和user_id
字段上创建索引。
CREATE INDEX idx_order_id ON orders(order_id); CREATE INDEX idx_user_id ON orders(user_id);
- 在
order_items
表的order_id
和product_id
字段上创建索引。
CREATE INDEX idx_order_id_oi ON order_items(order_id); CREATE INDEX idx_product_id_oi ON order_items(product_id);
- 在
products
表的product_id
和price
字段上创建索引。
CREATE INDEX idx_product_id_p ON products(product_id); CREATE INDEX idx_price_p ON products(price);
- 在
- 查询执行计划分析:
使用
EXPLAIN
关键字分析查询执行计划,查看MySQL如何执行查询,找出性能瓶颈。
EXPLAIN SELECT
o.user_id,
SUM(p.price * oi.quantity) AS total_price
FROM
orders o
JOIN
order_items oi ON o.order_id = oi.order_id
JOIN
products p ON oi.product_id = p.product_id
GROUP BY
o.user_id
ORDER BY
total_price DESC
LIMIT 10;
根据执行计划结果,进一步优化索引或调整查询结构。
3. 分区表:
如果数据量非常大,可以考虑对 orders
表和 order_items
表按时间(如月份、年份)进行分区,减少单次查询的数据量,提高查询性能。
例如,对 orders
表按年份分区:
CREATE TABLE orders (
order_id INT,
user_id INT,
order_time DATETIME,
-- 其他字段
)
PARTITION BY RANGE (YEAR(order_time)) (
PARTITION p0 VALUES LESS THAN (2020),
PARTITION p1 VALUES LESS THAN (2021),
PARTITION p2 VALUES LESS THAN (2022),
PARTITION p3 VALUES LESS THAN (2023),
PARTITION p4 VALUES LESS THAN (2024),
PARTITION p5 VALUES LESS THAN (MAXVALUE)
);
- 适当的表连接顺序:
在查询中,确保MySQL以最优的顺序连接表。一般来说,将小表放在
JOIN
操作的前面,这样MySQL可以快速过滤数据,减少中间结果集的大小。通过EXPLAIN
分析确定表连接顺序是否合理,并进行调整。 - 避免函数操作:
在
WHERE
子句、JOIN
条件或ORDER BY
子句中,避免对列进行函数操作,因为这会阻止索引的使用。例如,尽量不要在连接条件中使用函数对字段进行转换。 - 缓存查询结果: 虽然题目要求不考虑缓存,但在实际应用中,可以使用Memcached或Redis等缓存工具,将频繁查询的结果缓存起来,减少数据库的负载。