我是RedShift的新手,只是在这个阶段尝试帮助进行桌面设计。
我们有一个非常简单的表,大约有600万行和2个整数字段。
两个整数字段都在排序键中,但计划有一个警告 - “非常有选择性的查询过滤器”。
STL_Alert_Event_Log条目是: '非常有选择性的查询过滤器:ratio = rows(61)/ rows_pre_user_filter(524170)= 0.000116'
我们正在运行的查询是:
// Register some session variables!
**session_register('first_name');**
$_SESSION['first_name'] = $first_name;
**session_register('last_name');**
$_SESSION['last_name'] = $last_name;
**session_register('email_address');**
$_SESSION['email_address'] = $email_address;
**session_register('special_user');**
$_SESSION['user_level'] = $user_level;
我们的表DDL是:
select count(*)
from LargeNumberofRowswithUniKey r
where r.benchmarkid = 291891 and universeid = 300901
我们还在桌面上运行以下命令:
CREATE TABLE public.LargeNumberofRowswithUniKey
(
benchmarkid INTEGER NOT NULL DISTKEY,
UniverseID INTEGER NOT NULL
)
SORTKEY
(
benchmarkid,UniverseID
);
该计划的屏幕截图如下:[查询计划图片] [1] 我的期望是包括Benchmark和Universe在内的多重排序键以及两者都是过滤谓词的一部分,这将确保设计对于样本查询是最佳的。这似乎不是这种情况,因此附图中的红色警告符号。有人能说清楚这个吗?
由于
乔治
更新2017/09/07 我有更多可能有用的信息:
如果我运行一个更简单的查询,只是过滤排序键的第一列。
Vacuum full public.LargeNumberofRowswithUniKey;
Analyze public.LargeNumberofRowswithUniKey;
这导致根据控制台的实际查询计划扫描524,170行。当我使用STV_BLOCKLIST查看块时。满足我的查询可能需要的相关块是:
select r.benchmarkid
from LargeNumberofRowswithUniKey r
where r.benchmarkid = 291891
所以不应该扫描786,255行(3 x 262,085)而不是计划中列出的524,170(2 x 262,085)?
答案 0 :(得分:2)
the rows selected vs rows scanned ratio is less than 0.05时返回“非常有选择性的过滤器”警告,即与实际返回的行数相比扫描的行数相对较多。这可能是因为表中有大量未排序的行,可以通过运行真空来解决。但是,正如您已经在做的那样,我认为这种情况正在发生,因为您的查询实际上是非常有选择性的(您选择的是baselineid和universeid的单一组合),因此您可能会忽略此警告。
答案 1 :(得分:2)
侧面观察:如果您始终同时使用benchmarkid
和UniverseID
选择值,则应该使用DISTKEY EVEN
。
原因是benchmarkid DISTKEY
会根据benchmarkid
在切片之间分配数据。给定benchmarkid
的所有值都在同一个切片上。如果您的查询始终在查询中提供benchmarkid
,则查询仅使用一个切片。
另一方面,如果它使用DISTKEY EVEN
,那么每个切片都可以参与查询,从而提高效率(对于WHERE benchmarkid = xxx
的查询)。
一般的经验法则是:
DISTKEY
用于JOIN或GROUP BY SORTKEY
用于WHERE