原查询

SELECT DISTINCT(class)
FROM ship
WHERE manufacturer_id IN (
SELECT manufacturer_id
FROM manufacturer
WHERE state = ‘CA’
);


改进方法

方法 1:使用 JOIN 提高可读性

通过 JOIN 重写查询,可以让逻辑更清晰:

SELECT DISTINCT(ship.class)
FROM ship
JOIN manufacturer
ON ship.manufacturer_id = manufacturer.manufacturer_id
WHERE manufacturer.state = ‘CA’;

优点:

JOIN 的写法更直观,特别是当数据表之间关系明确时。

一些数据库管理系统(如 MySQL)对 JOIN 的性能优化可能优于子查询。


方法 2:避免 DISTINCT(如果可能)

如果确定每个 manufacturer_id 对应唯一的 class,可以省略 DISTINCT,提高查询效率:

SELECT ship.class
FROM ship
JOIN manufacturer
ON ship.manufacturer_id = manufacturer.manufacturer_id
WHERE manufacturer.state = ‘CA’;

注意:只有在 class 本身没有重复的情况下才能去掉 DISTINCT。


方法 3:EXISTS 替代 IN

使用 EXISTS 代替 IN,在某些情况下,EXISTS 的性能可能更优,特别是在子查询返回大量结果时:

SELECT DISTINCT(class)
FROM ship
WHERE EXISTS (
SELECT 1
FROM manufacturer
WHERE ship.manufacturer_id = manufacturer.manufacturer_id
AND manufacturer.state = ‘CA’
);

优点:

EXISTS 优化:通过短路机制避免加载完整结果集,仅检查是否存在匹配记录。

IN 的特性:必须先构造完整的子查询结果集(一个列表),再逐行比较。

如果子查询的结果集较大,EXISTS 通常比 IN 性能更优。


方法 4:简化列选择

如果你仅关心结果而不需要特定的列名前缀,可以去掉冗余的表名或字段引用:

SELECT DISTINCT(class)
FROM ship
WHERE manufacturer_id IN (
SELECT manufacturer_id
FROM manufacturer
WHERE state = ‘CA’
);


性能优化建议

  1. 索引优化:

为 manufacturer.manufacturer_id 和 manufacturer.state 列添加索引,可以显著提高查询性能。

同样,为 ship.manufacturer_id 添加索引也有助于提高 JOIN 或 IN 操作的速度。

  1. 查询场景评估:

如果 manufacturer 表中 state = ‘CA’ 的记录非常多,使用 JOIN 或 EXISTS 的查询性能通常优于 IN。

如果子查询结果非常小,IN 的性能可能更高。


最终推荐

选择适合具体数据库优化和需求的版本。推荐的查询为:

SELECT DISTINCT(ship.class)
FROM ship
JOIN manufacturer
ON ship.manufacturer_id = manufacturer.manufacturer_id
WHERE manufacturer.state = ‘CA’;