MST

星途 面试题库

面试题:MySQL查询语句优化之避免SELECT * - 专家难度

在一个复杂的电商数据库环境中,存在`products`表(包含众多产品相关字段)、`orders`表(记录订单信息)、`order_items`表(关联订单与产品及数量等信息)。业务需求是获取每个订单中购买数量最多的产品的详细信息(假设产品详细信息只需`product_id`、`product_name`、`price`)以及该订单的总金额。请给出完整且优化的SQL查询方案,并深入分析使用`SELECT *`会对查询性能、数据库资源以及系统扩展性产生哪些严重影响。
27.5万 热度难度
数据库MySQL

知识考点

AI 面试

面试题答案

一键面试

SQL查询方案

WITH RankedOrderItems AS (
    SELECT 
        oi.order_id, 
        oi.product_id, 
        oi.quantity, 
        p.product_name, 
        p.price,
        ROW_NUMBER() OVER (PARTITION BY oi.order_id ORDER BY oi.quantity DESC) AS rn
    FROM 
        order_items oi
    JOIN 
        products p ON oi.product_id = p.product_id
),
OrderTotalAmount AS (
    SELECT 
        order_id, 
        SUM(oi.quantity * p.price) AS total_amount
    FROM 
        order_items oi
    JOIN 
        products p ON oi.product_id = p.product_id
    GROUP BY 
        order_id
)
SELECT 
    roi.order_id, 
    roi.product_id, 
    roi.product_name, 
    roi.price, 
    ota.total_amount
FROM 
    RankedOrderItems roi
JOIN 
    OrderTotalAmount ota ON roi.order_id = ota.order_id
WHERE 
    roi.rn = 1;

使用 SELECT * 的影响分析

  1. 查询性能

    • 增加数据传输量SELECT * 会返回表中的所有列,而不管实际需要哪些列。在复杂的电商数据库环境中,products 表可能包含众多字段,如产品描述、图片路径等大文本或二进制数据。这会导致大量不必要的数据从数据库服务器传输到应用程序,增加网络带宽的占用,从而降低查询性能。
    • 索引使用受限:数据库查询优化器在执行查询时,会根据索引来快速定位数据。当使用 SELECT * 时,如果查询条件中没有涉及到所有列,优化器可能无法有效地使用索引,导致全表扫描,大大增加查询时间。
  2. 数据库资源

    • 增加磁盘I/O:由于要读取更多的数据,数据库需要从磁盘中读取更多的页面,增加了磁盘I/O操作。频繁的磁盘I/O会导致磁盘性能瓶颈,影响整个数据库系统的性能。
    • 增加内存消耗:数据库在处理查询时,会将数据加载到内存中进行处理。SELECT * 导致更多的数据被加载到内存,可能会超出数据库服务器的内存容量,从而导致内存交换,进一步降低系统性能。
  3. 系统扩展性

    • 架构变更风险:如果表结构发生变化,例如添加或删除列,使用 SELECT * 的查询可能会受到影响。应用程序可能会因为新列的出现而出现兼容性问题,或者因为删除列而导致数据丢失或程序错误,增加了系统维护和扩展的风险。
    • 性能优化困难:随着业务的发展,数据库的规模和复杂度会不断增加。使用 SELECT * 会使得查询性能问题在后期难以优化,因为难以确定哪些数据是真正需要的,不利于针对性地进行索引优化和查询改写。