【问题标题】:Optimizing join in vertica优化垂直连接
【发布时间】:2015-08-26 21:41:39
【问题描述】:

我有一个这样的查询

SELECT a.column, b.column
FROM
table_a a INNER JOIN tableb_b ON
a.id= b.id
where a.anotherid = 'some condition'

它应该非常快,因为使用谓词 a.anotherid = 'some condition' 查询计划应该过滤 table_b 上的大量数据。 但是根据Vertica的文档,

WHERE 子句在 执行连接之后进行评估。它过滤 FROM 子句返回的记录,消除任何记录 不满足 WHERE 子句条件。

也就是说查询会先join再过滤,很慢,这在查询计划中也有体现

那么,有没有办法在加入之前推送过滤器? 或者有没有其他方法可以优化查询?

【问题讨论】:

  • 只做 ON a.id= b.id AND a.anotherid = 'some condition'?
  • 如果您查看查询,这就是现在的样子
  • 我仍然看到 WHERE 子句...
  • SELECT a.column, b.column FROM table_a a INNER JOIN tableb_b ON a.id= b.id and a.anotherid = 'some condition' 仍然不起作用,: (
  • 性能方面有什么不同吗?

标签: sql database vertica


【解决方案1】:
  1. EXPLAIN 显示NO STATISTICS。这些必须是updated
  2. Vertica 将在这种情况下使用 SIP 优化谓词:

通过在计划中尽早过滤数据,横向信息传递 (SIP) 有效地提高了连接性能。它可以被认为是谓词下推的高级变体,因为连接被用于进行过滤[27]。例如,考虑一个使用简单相等谓词连接两个表的 HashJoin。 HashJoin 将首先从内部输入创建一个哈希表,然后再开始从外部输入读取数据以进行连接。特殊 SIP 过滤器在优化器规划期间构建并放置在 Scan 操作器中。在运行时,Scan 可以访问 Join 的哈希表,并且 SIP 过滤器用于评估哈希表中是否存在外键值。未通过这些过滤器的行不会由 Scan 输出,从而提高性能,因为我们不会不必要地通过计划将数据带入,只是稍后被连接过滤掉。

例如:

SELECT a.online_page_key
FROM   online_sales.online_sales_fact a
       JOIN online_sales.online_page_dimension b
         ON b.online_page_key = a.online_page_key
WHERE  b.page_type = 'quarterly';

将产生与以下相同的计划:

SELECT a.online_page_key 
FROM   online_sales.online_sales_fact a 
       JOIN (SELECT * 
             FROM   online_sales.online_page_dimension 
             WHERE  page_type = 'quarterly') b 
         ON b.online_page_key = a.online_page_key;

看起来像:

 Access Path:
 +-JOIN HASH [Cost: 14K, Rows: 988K] (PATH ID: 1)
 |  Join Cond: (online_page_dimension.online_page_key = a.online_page_key)
 | +-- Outer -> STORAGE ACCESS for a [Cost: 12K, Rows: 5M] (PATH ID: 2)
 | |      Projection: online_sales.online_sales_fact_super
 | |      Materialize: a.online_page_key
 | |      Runtime Filter: (SIP1(HashJoin): a.online_page_key)
 | +-- Inner -> STORAGE ACCESS for online_page_dimension [Cost: 36, Rows: 198] (PATH ID: 3)
 | |      Projection: online_sales.online_page_dimension_super
 | |      Materialize: online_page_dimension.online_page_key
 | |      Filter: (online_page_dimension.page_type = 'quarterly')
  1. 大多数时候,散列连接就足够了。如果您想改进合并连接,请参阅我在 optimizing for merge join 上的帖子。

【讨论】:

  • 那真的很有帮助,数据库分析完表后,成功下推过滤器。如果我需要进一步提高性能,将哈希联接更改为合并联接有帮助吗?你有关于这个话题的文章吗?非常感谢。
  • @JadeTang 不一定。按照答案底部的我的博客文章的链接。 “合并连接总是比哈希连接更有效,但不一定更快。如果数据集很小,哈希连接可能处理得更快。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 2018-02-26
  • 2011-05-22
  • 2011-12-31
相关资源
最近更新 更多