关于sql:什么是LIMIT的有效替代方案?

What's an Efficient Alternative to LIMIT?

我的问题基本上是:在第一次匹配WHERE条件后,如何告诉数据库进行seq扫描并停止?

假设我要查找某个类型的第一个事件,我可以编写以下查询:

1
2
3
4
5
SELECT *
FROM installs
WHERE country = 'China'
ORDER BY install_date
LIMIT 1

这里的问题是,引擎将根据操作顺序扫描所有表并生成与我的过滤器匹配的数据集,然后对该数据集进行排序(成本很高),然后仅返回第一行。 >

我当然可以按特定日期进行过滤,但让我们假设我不知道要过滤的时间段-如何在Amazon Redshift中优化这种类型的查询(可能在where子句中)?


Redshift的一般策略是进行大量扫描,但要并行进行。任何涉及获取单行的情况都不是理想的。也就是说,您可以做四件事:

1。减少扫描到一点

如果始终将国家/地区作为过滤字段,请先将表格的排序键设置为国家/地区上的复合排序键。

2。消除排序的必要性

ORDER BY x LIMIT 1的一种更有效的方法通常是MAX。

然后尝试

1
2
3
4
5
6
7
SELECT *
FROM installs
WHERE pk = (
  SELECT MAX(pk)  -- or install_date, if install date is unique
  FROM installs
  WHERE country = 'China'
)

3。在面向行和columnar

之间调整选定的列

要求像Redshift这样的列式数据库选择*会产生每一列的成本。尝试仅选择所需的列。

4。添加更多节点,因此每个节点执行的扫描次数更少

(确保未将数据全部设置为分布样式)


如果删除ORDER BY,则它可以有效地工作。

对结果进行排序的要求意味着它需要检查该国家/地区为中国的所有行,这对于返回一件商品而言效率不高。

如果SORTKEY = country,则where country = 'China'子句很有效,因为它可以跳过任何不包含所需值的存储块。如果匹配的行相对很少,这将非常高效。

如果您经常查询单行结果,则可能需要将此类信息存储在单独的表中以加快查找速度。该值可以根据需要每天或每小时计算一次。