Teradata中SELECT TOP 1与SAMPLE 1的性能差异问询
Teradata中SELECT TOP 1与SAMPLE 1的性能差异分析
问题现象
执行select top 1 * from x.y时排队长达一小时,而select * from x.y sample 1仅需几秒即可完成。有人解释称select top会收集所有数据并排序后取前1行,sample 1只是随机获取一行无需排序,但对此存疑——因为查询未包含ORDER BY,且两者的数据库使用指标差一个数量级。
查询指标对比
| AMPCPUTime | StartTime | FirstStepTime | FirstRespTime | Spool_Usage_GB | TotalIOCount | QueryText |
|---|---|---|---|---|---|---|
| 2.92 | 10:57:37.52 | 10:57:37.52 | 10:57:37.92 | 0 | 24248 | select * from x.y sample 1; |
| 0.02 | 9:30:08.39 | 10:57:37.10 | 10:57:37.26 | 0 | 55 | SELECT TOP 1 * FROM x.y; |
执行计划分析
EXPLAIN SELECT TOP 1 * FROM x.y;
- 首先,为防止全局死锁,在TD_MAP1中对x.y加读锁,锁定保留的RowHash。
- 接下来,在TD_MAP1中对x.y加读锁。
- 在TD_MAP1中执行全AMP统计函数步骤:对x.y进行全表扫描,无残留条件,结果存入TD_Map1中AMP本地构建的Spool 5;结果行存入AMP本地构建的Spool 1(group_amps),此步骤用于获取TOP 1行。随机选择一个AMP获取1行,若获取行数不足1行则执行步骤4。预估行数为1行(594字节),置信度高,预估耗时1分34秒。
- 在TD_MAP1中执行全AMP统计函数步骤:对x.y进行全表扫描,无残留条件,结果存入Spool 5(最后使用),按哈希码重分布至TD_Map1的所有AMP;结果行存入AMP本地构建的Spool 1(group_amps),此步骤用于获取TOP 1行。预估行数为1行(594字节),置信度高,预估耗时1分34秒。
- 执行组AMP排序,按Spool 1(group_amps)中spool field1的排序键排序。
- 最后,向所有参与处理的AMP发送END TRANSACTION步骤。
-> Spool 1的内容作为语句1的结果返回给用户。
EXPLAIN select * from x.y sample 1;
- 首先,为防止全局死锁,在TD_MAP1中对x.y加读锁,锁定保留的RowHash。
- 接下来,在TD_MAP1中对x.y加读锁。
- 在TD_MAP1中执行全AMP采样步骤:对x.y进行全表扫描,无残留条件,结果存入AMP本地构建的Spool 1(group_amps),采样指定为行数。Spool 1预估行数为1行(594字节),置信度高。
- 最后,向所有参与处理的AMP发送END TRANSACTION步骤。
-> Spool 1的内容作为语句1的结果返回给用户。
差异原因解析
从执行计划和指标数据可以明确两者的性能差异根源:
- SELECT TOP 1:即使未显式指定ORDER BY,Teradata内部仍会默认基于某个spool字段执行组AMP排序操作,以确定“TOP 1”的结果行。同时执行计划中的全AMP统计步骤可能触发全表扫描,再加上跨AMP的数据处理逻辑,导致查询在资源队列中长时间等待(从StartTime和FirstStepTime的时间差可看出排队时长超1小时),最终整体耗时极高。
- SAMPLE 1:采用AMP本地随机采样逻辑,每个AMP独立完成采样后直接返回结果,无需跨AMP的数据聚合或排序操作。虽然同样会进行全表扫描,但采样逻辑轻量,无额外排序开销,因此几乎没有排队,几秒即可完成。
社区讨论补充
关于Teradata中TOP与SAMPLE的效率对比,业内共识如下:
- 未指定ORDER BY的
TOP N查询,优化器可能会选择全表扫描+排序的执行路径,因为需要通过内部排序键确定结果顺序,即使仅需少量行,也会产生额外开销。 SAMPLE N是基于AMP级别的随机采样,避免了跨节点的数据传输和排序,在仅需获取少量随机样本时,性能远优于无ORDER BY的TOP查询。
内容的提问来源于Stack Exchange,提问作者sylvyr3
相关产品推荐
相关产品推荐

