请考虑下表:
name salary
----- --------
a 100
b 200
c 300
d 300 -- note the duplicate max
现在,我们要使用以下查询来计算第二个最高工资:
SELECT max(salary)
FROM emptable
WHERE salary < (SELECT max(salary)
FROM emptable);
那么MySQL将如何确定该查询的结果?例如,我假设首先将执行where
子句中的子查询并确定最高薪水,将其命名为M1
(将为400
)并将其存储在一些变量。然后它将从原始表400
中找到最高薪水,但不满足where
子句中的约束(即,将其与M1
进行比较)。现在,它将复制原始表,并删除包含此(400
)值的元组,因为它不满足约束条件,并重复此过程,直到找到所需的结果。
很可能我错了,但是我写了以上过程只是为了澄清我的问题。
答案 0 :(得分:1)
出现在WHERE
子句中的子查询与外部查询不相关,因此优化程序很可能会对其进行一次计算,然后将结果缓存到某个位置。此后,最大值将用于过滤掉具有该最大值的一个或多个记录。然后,这只是一个典型的最大查询。为了确认这一点,或者发现我可能错过的东西,您可以对查询运行EXPLAIN
。
顺便说一句,您也可以使用LIMIT
和OFFSET
编写此查询:
SELECT DISTINCT salary
FROM emptable
ORDER BY salary DESC
LIMIT 1
OFFSET 1;
这还应该返回排名第二高的薪水(即,对于相同薪水中有不止一个薪水是稳健的)。但是这种方法可以很容易地找到薪水的任何等级,而子查询方法却不能很好地扩展。
答案 1 :(得分:0)
查询优化器可以自由地进行任何优化(基于索引/数据分配/ ...)。您应该始终检查实际的执行计划:
explain
SELECT max(salary)
FROM emptable
WHERE salary < (SELECT max(salary)
FROM emptable);
输出:
┌────┬─────────────┬──────────┬──────┬───────────────┬──────┬─────────┬──────┬──────┬─────────────┐
│ id │ select_type │ table │ type │ possible_keys │ key │ key_len │ ref │ rows │ Extra │
├────┼─────────────┼──────────┼──────┼───────────────┼──────┼─────────┼──────┼──────┼─────────────┤
│ 1 │ PRIMARY │ emptable │ ALL │ null │ null │ null │ null │ 4 │ Using where │
│ 2 │ SUBQUERY │ emptable │ ALL │ null │ null │ null │ null │ 4 │ │
└────┴─────────────┴──────────┴──────┴───────────────┴──────┴─────────┴──────┴──────┴─────────────┘
并且薪水为INDEX
:
create index idx ON emptable(salary);
┌────┬─────────────┬───────┬──────┬───────────────┬──────┬─────────┬──────┬──────┬──────────────────────────────┐
│ id │ select_type │ table │ type │ possible_keys │ key │ key_len │ ref │ rows │ Extra │
├────┼─────────────┼───────┼──────┼───────────────┼──────┼─────────┼──────┼──────┼──────────────────────────────┤
│ 1 │ PRIMARY │ null │ null │ null │ null │ null │ null │ null │ Select tables optimized away │
│ 2 │ SUBQUERY │ null │ null │ null │ null │ null │ null │ null │ Select tables optimized away │
└────┴─────────────┴───────┴──────┴───────────────┴──────┴─────────┴──────┴──────┴──────────────────────────────┘
答案 2 :(得分:0)
您想要“密集排名”。
以下公式 可能会得到更好的优化,因此如果您的表很大,则会更快:
chunkSize
这需要
bytesRead