当我运行两个看似相似的查询时,我对Redshift正在做什么感到困惑。也不应该返回结果(查询不存在的配置文件)。具体做法是:
SELECT * FROM profile WHERE id = 'id_that_doesnt_exist' and project_id = 1;
Execution time: 36.75s
与
SELECT COUNT(*) FROM profile WHERE id = 'id_that_doesnt_exist' and project_id = 1;
Execution time: 0.2s
鉴于该表按project_id
排序,然后id
我认为这只是一个关键查找。 SELECT COUNT(*) ...
返回0结果为0.2秒,这与我的期望大致相同。 SELECT * ...
返回0结果为37.75秒。对于相同的结果,这是一个巨大的差异,我不明白为什么?
如果它有助于架构如下:
CREATE TABLE profile (
project_id integer not null,
id varchar(256) not null,
created timestamp not null,
/* ... approx 50 other columns here */
)
DISTKEY(id)
SORTKEY(project_id, id);
从SELECT COUNT(*) ...
XN Aggregate (cost=435.70..435.70 rows=1 width=0)
-> XN Seq Scan on profile (cost=0.00..435.70 rows=1 width=0)
Filter: (((id)::text = 'id_that_doesnt_exist'::text) AND (project_id = 1))
从SELECT * ...
XN Seq Scan on profile (cost=0.00..435.70 rows=1 width=7356)
Filter: (((id)::text = 'id_that_doesnt_exist'::text) AND (project_id = 1))
为什么非计数要慢得多?当然Redshift知道行不存在吗?
答案 0 :(得分:1)
原因是:在许多RDBMS中,关于count(*)问题的答案通常没有实际的数据扫描:仅来自索引或表统计信息。 Redshift存储曾经存在或不存在答案的块的最小值和最大值,例如在描述情况下。如果在最小/最大块边界内请求值,则仅对过滤字段数据执行扫描。如果请求的值是较低或较高的块边界,则根据存储的统计数据,可以更快地给出答案。如果是"选择*"问题RedShift实际扫描查询中询问的所有列数据:" *"但只能按"中的列过滤"子句。