SQL查询优化改写求助:聚合分组与多OR条件查询语句优化
SQL查询优化方案
第一条SQL优化
原始问题SQL
SELECT w.wname, SUM(w.price) sold_total, FROM wine w GROUP BY w.wname;
第一步:语法修正
原始SQL存在语法错误:sold_total 后多了冗余逗号,同时建议加上 AS 明确别名提升可读性,修正后基础版本:
SELECT w.wname, SUM(w.price) AS sold_total FROM wine w GROUP BY w.wname;
性能优化方案
你提到的「创建对应对象」指的是覆盖索引,是该场景下的最优优化手段:
- 针对该聚合查询创建联合索引
idx_wine_wname_price (wname, price) - 优化逻辑:索引本身已经包含了查询需要的
wname和price两个字段,数据库可以直接扫描索引完成聚合计算,不需要回表访问原表数据,数据量越大优化效果越明显 - 附加优化:如果只需要返回销售额满足阈值的结果,可以增加
HAVING条件提前过滤,减少返回数据量,示例:SELECT w.wname, SUM(w.price) AS sold_total FROM wine w GROUP BY w.wname HAVING SUM(w.price) > 1000;
第二条SQL优化
原始问题SQL
SELECT * from class WHERE CID = 'RIES ' OR CID = 'CHARDN' OR CID = 'PINOT';
第一步:语法优化
多个等值OR条件可以改写为IN语法,可读性更强,数据库执行计划和原写法完全一致:
-- 注意'RIES '末尾的空格请确认是否为业务需要,避免匹配错误 SELECT * FROM class WHERE CID IN ('RIES ', 'CHARDN', 'PINOT');
性能优化方案
1. 绑定变量实现(适配你提到的优化思路)
- 适用场景:该查询在应用代码中频繁执行,每次传入的CID值是动态变化的
- 实现逻辑:用占位符替代硬编码的CID值,数据库可以复用同逻辑的执行计划,避免每次查询都进行硬解析,降低CPU开销,同时可以避免SQL注入风险
- 示例(以JDBC为例):
// SQL模板用?做占位符 String sql = "SELECT * FROM class WHERE CID IN (?, ?, ?)"; PreparedStatement pstmt = connection.prepareStatement(sql); // 按顺序给占位符赋值 pstmt.setString(1, "RIES "); pstmt.setString(2, "CHARDN"); pstmt.setString(3, "PINOT"); ResultSet rs = pstmt.executeQuery();
2. 索引优化
如果CID字段区分度较高(不同CID值占总数据量的比例低于20%),可以在CID字段上创建单列索引idx_class_cid (CID),避免全表扫描,查询效率可以提升数倍到数十倍。
3. 附加优化
尽量避免使用SELECT *,明确写出需要查询的字段,减少数据传输开销。如果查询的字段固定,可以创建覆盖索引进一步提升性能,例如需要查询CID、className、teacher三个字段,可以创建索引idx_class_cid_cover (CID) INCLUDE (className, teacher)。
内容的提问来源于stack exchange,提问作者Student Work
相关产品推荐
相关产品推荐

