MySQL 的 LIMIT 和 Teradata 的 TOP 在对非索引变量进行调节时的区别
Difference between MySQL's LIMIT and Teradata's TOP when conditioning on non-indexed variables
今天上班,我尝试在 Teradata 中执行以下命令但失败了:
SELECT TOP 10 * FROM tab WHERE col <> 1
正如一位同事后来向我解释的那样,Teradata 首先 运行 在整个 table 上设置 WHERE
条件(太大了),然后再选择 TOP 10
。据我的同事说,如果 col
被编入索引,情况会有所不同。
现在我想知道 MySQL 是否真的在做同样的事情;可能我只是从来没有足够地突破界限。是否
SELECT * FROM tab WHERE col != 1 LIMIT 10
在返回前 10 个之前 运行 整个 table 的 col != 1
条件(如果这改变了答案,让 col
不被索引)?
提前致谢。
首先,你不应该使用 LIMIT / TOP
除非你也使用 ORDER BY
,如果你对 return 到底是什么感兴趣(除了有这么多记录的事实完全没有)。
话虽如此,MySQL 将 不会 扫描整个 table(如果 tab
是 table)或在 return 对 LIMIT
记录进行索引之前:它将 return 记录扫描和过滤它们,并且一旦有足够的记录就会停止。
但是,如果 tab
不是 table,而是一个视图,并且如果它包含嵌套查询,或 GROUP BY
条件或类似的东西,MySQL 可能需要在过滤和限制之前扫描所有底层 tables。
在像 Teradata 这样的大型并行 DBMS 上,情况有所不同。一个系统可能包含数百个物理服务器和数千个 AMP(Teradata "instances"),并且一个 table 分布在系统中的所有 AMP 中,正如@Shadow 在评论中已经提到的那样。
现在,当您提交带有任何 WHERE
条件(或连接或聚合)的 TOP
时,系统实际上会首先创建一个包含所有过滤行的中间假脱机,然后应用顶级逻辑.您可以很容易地看到,当您 EXPLAIN
查询时,最后一步包括一个 STAT FUNCTION ... 用于检索前 10 行.
您这样做可能是为了快速查看数据,因此您可以删除 WHERE
-条件,然后它真的很快,因为单个 AMP 将只读取其第一个数据块。如果你真的需要过滤后的数据,你可以使用这个:
SELECT TOP 10 *
FROM
(
SELECT TOP 1000 *
FROM tab
) AS dt
WHERE col <> 1
在 Derived Table 中使用 TOP n
,它足够大 return 至少 10 行匹配外部条件。
今天上班,我尝试在 Teradata 中执行以下命令但失败了:
SELECT TOP 10 * FROM tab WHERE col <> 1
正如一位同事后来向我解释的那样,Teradata 首先 运行 在整个 table 上设置 WHERE
条件(太大了),然后再选择 TOP 10
。据我的同事说,如果 col
被编入索引,情况会有所不同。
现在我想知道 MySQL 是否真的在做同样的事情;可能我只是从来没有足够地突破界限。是否
SELECT * FROM tab WHERE col != 1 LIMIT 10
在返回前 10 个之前 运行 整个 table 的 col != 1
条件(如果这改变了答案,让 col
不被索引)?
提前致谢。
首先,你不应该使用 LIMIT / TOP
除非你也使用 ORDER BY
,如果你对 return 到底是什么感兴趣(除了有这么多记录的事实完全没有)。
话虽如此,MySQL 将 不会 扫描整个 table(如果 tab
是 table)或在 return 对 LIMIT
记录进行索引之前:它将 return 记录扫描和过滤它们,并且一旦有足够的记录就会停止。
但是,如果 tab
不是 table,而是一个视图,并且如果它包含嵌套查询,或 GROUP BY
条件或类似的东西,MySQL 可能需要在过滤和限制之前扫描所有底层 tables。
在像 Teradata 这样的大型并行 DBMS 上,情况有所不同。一个系统可能包含数百个物理服务器和数千个 AMP(Teradata "instances"),并且一个 table 分布在系统中的所有 AMP 中,正如@Shadow 在评论中已经提到的那样。
现在,当您提交带有任何 WHERE
条件(或连接或聚合)的 TOP
时,系统实际上会首先创建一个包含所有过滤行的中间假脱机,然后应用顶级逻辑.您可以很容易地看到,当您 EXPLAIN
查询时,最后一步包括一个 STAT FUNCTION ... 用于检索前 10 行.
您这样做可能是为了快速查看数据,因此您可以删除 WHERE
-条件,然后它真的很快,因为单个 AMP 将只读取其第一个数据块。如果你真的需要过滤后的数据,你可以使用这个:
SELECT TOP 10 *
FROM
(
SELECT TOP 1000 *
FROM tab
) AS dt
WHERE col <> 1
在 Derived Table 中使用 TOP n
,它足够大 return 至少 10 行匹配外部条件。