使用 `COUNT` 优化 SQL 查询
Optimize SQL query using `COUNT`
我有下面的 SQL 查询(我正在使用 MariaDB/MySQL),它工作正常。但我想知道我是否可以 simplify/optimize 它。我面临的困难是因为 COUNT
和 INNER JOIN
。我真的需要子查询 IN
还是您认为我有办法消除它?
SELECT a.*
FROM aaa a
INNER JOIN bbb b ON a.field1 = b.field1
WHERE a.yyy = 'yyy' AND b.zzz = 'zzz'
AND a.field1 IN (
SELECT field1
FROM bbb
WHERE xxx = 'x'
GROUP BY field1
HAVING COUNT(field1) <= 5
)
谢谢!
您的查询可能会尽可能好,但您也可以尝试加入子查询而不是使用 IN
。
SELECT DISTINCT a.*
FROM aaa AS a
INNER JOIN bbb b ON a.field1 = b.field1
INNER JOIN (
SELECT field1
FROM bbb
WHERE xxx = 'x'
GROUP BY field1
HAVING COUNT(*) <= 5
) AS bc ON a.field1 = bc.field1
WHERE a.yyy = 'yyy' AND b.zzz = 'zzz'
我喜欢 Barmar 的回答,但由于 b
上的过滤,我建议进行小的(?)更改。 (我重新排列表格主要是为了遵循优化器可能的顺序。)
SELECT DISTINCT a.*
FROM (
SELECT field1
FROM bbb
WHERE xxx = 'x'
GROUP BY field1
HAVING COUNT(*) <= 5
) AS bc
INNER JOIN bbb AS b ON b.field1 = bc.field1
INNER JOIN aaa AS a ON a.field1 = bc.field1
WHERE b.zzz = 'zzz'
AND a.yyy = 'yyy'
加上这些索引:
bbb: INDEX(xxx, field1) -- this order
b: INDEX(field1, zzz) -- either order
a: INDEX(field1, yyy) -- either order
前两个复合索引将被“覆盖”。
Barmar 回答的主要变化是将 a.*
留在最后。
如果您想进一步讨论这个问题,提供 SHOW CREATE TABLE
和 EXPLAIN
可能会有用。
我有下面的 SQL 查询(我正在使用 MariaDB/MySQL),它工作正常。但我想知道我是否可以 simplify/optimize 它。我面临的困难是因为 COUNT
和 INNER JOIN
。我真的需要子查询 IN
还是您认为我有办法消除它?
SELECT a.*
FROM aaa a
INNER JOIN bbb b ON a.field1 = b.field1
WHERE a.yyy = 'yyy' AND b.zzz = 'zzz'
AND a.field1 IN (
SELECT field1
FROM bbb
WHERE xxx = 'x'
GROUP BY field1
HAVING COUNT(field1) <= 5
)
谢谢!
您的查询可能会尽可能好,但您也可以尝试加入子查询而不是使用 IN
。
SELECT DISTINCT a.*
FROM aaa AS a
INNER JOIN bbb b ON a.field1 = b.field1
INNER JOIN (
SELECT field1
FROM bbb
WHERE xxx = 'x'
GROUP BY field1
HAVING COUNT(*) <= 5
) AS bc ON a.field1 = bc.field1
WHERE a.yyy = 'yyy' AND b.zzz = 'zzz'
我喜欢 Barmar 的回答,但由于 b
上的过滤,我建议进行小的(?)更改。 (我重新排列表格主要是为了遵循优化器可能的顺序。)
SELECT DISTINCT a.*
FROM (
SELECT field1
FROM bbb
WHERE xxx = 'x'
GROUP BY field1
HAVING COUNT(*) <= 5
) AS bc
INNER JOIN bbb AS b ON b.field1 = bc.field1
INNER JOIN aaa AS a ON a.field1 = bc.field1
WHERE b.zzz = 'zzz'
AND a.yyy = 'yyy'
加上这些索引:
bbb: INDEX(xxx, field1) -- this order
b: INDEX(field1, zzz) -- either order
a: INDEX(field1, yyy) -- either order
前两个复合索引将被“覆盖”。
Barmar 回答的主要变化是将 a.*
留在最后。
如果您想进一步讨论这个问题,提供 SHOW CREATE TABLE
和 EXPLAIN
可能会有用。