我的排序键是否被使用?

时间:2018-05-04 00:36:06

标签: amazon-web-services amazon-redshift

我有一个列updated_at的表,这是一个排序键。在桌面上同时运行VACUUMANALYZE后,这是我在updated_at上过滤时获得的查询计划:

EXPLAIN
SELECT *
FROM my_table
WHERE updated_at > '2018-01-01';

QUERY PLAN
XN Seq Scan on my_table  (cost=0.00..0.00 rows=1 width=723)
  Filter: (updated_at > '2018-01-01 00:00:00'::timestamp without time zone)

我的理解是,尽管有排序键,查询执行引擎正在对表进行顺序扫描,因此排序键没有做任何事情?

2 个答案:

答案 0 :(得分:3)

查看Redshift文档中的"Analyzing the Query Summary" section。它显示了如何使用SVL_QUERY_SUMMARY视图观察每个查询执行的非常详细的指标。

对于最有效排序密钥用法,您应该会看到rr_scan(范围限制扫描)列设置为tnum_rows_pre_filter应该非常接近至rows计数。 num_rows_pre_filter是应用谓词过滤器之前从磁盘扫描的行数。注意:在这种情况下,“相当接近”会因您的具体数据而异。

SELECT stm,seg,step,TRIM(LEFT(label,30))"label"
      ,rows_pre_filter,rows,avgtime,bytes,is_rrscan 
FROM svl_query_summary 
WHERE query  = 123456
ORDER BY stm ,seg ,step; 

| stm | seg | step |             label             | rows_pre_filter | rows | avgtime | bytes | is_rrscan |
|-----|-----|------|-------------------------------|-----------------|------|---------|-------|-----------|
|   0 |   0 |    0 | scan   tbl=428142 name=my_tbl |          103665 |    6 |   52814 |  1273 | t         |
|   0 |   0 |    1 | project                       |               0 |    6 |   52814 |     0 | f         |
|   0 |   0 |    2 | sort   tbl=303                |               0 |    6 |   52814 |  1288 | f         |
|   1 |   1 |    0 | scan   tbl=303 name=Internal  |               0 |    6 |      74 |  1288 | f         |
|   1 |   1 |    1 | return                        |               0 |    6 |      74 |     0 | f         |
|   1 |   2 |    0 | merge                         |               0 |    0 |     275 |     0 | f         |
|   1 |   2 |    1 | project                       |               0 |    6 |     275 |     0 | f         |
|   1 |   2 |    2 | return                        |               0 |    6 |     275 |  1387 | f         |

答案 1 :(得分:2)

顺序扫描在Amazon Redshift上完全正常,因为它不使用索引。

系统非常智能,可以跳过块不包含所需的值,因为每个块(只包含一列的数据)存储块中每个值的最小值和最大值。因此,将自动跳过包含2018-01-01之前所有日期的块。

这不会出现在EXPLAIN计划中,因为它取决于每个块中存储的实际数据。

最好的办法是运行一些测试,看看它是否正在快速运行,正如您所期望的那样。您可能希望运行SET enable_result_cache_for_session TO OFF以阻止缓存影响结果。

此外,尽量避免将SORT KEY转换为其他类型的情况。在上面的示例中,如果列是DATE但查询将其用作TIMESTAMP,则它可能无法跳过块,因为它必须在从磁盘读取后转换值。因此,如果WHERE使用完全相同的数据类型,它可能会更好。