Vertica和加入

时间:2012-11-23 14:42:06

标签: sql join vertica

我正在调整网络分析工具以使用Vertica作为数据库。我遇到了真正的问题optimizing joins。我尝试为我的一些查询创建预连接投影,虽然它确实使查询变得非常快,但它减慢了数据加载到事实表中的速度。

我们用来从临时表中将数据加载到事实表中的简单INSERT INTO ... SELECT * FROM从花费大约5秒钟到花费20多分钟。

因此我删除了所有预连接投影,并尝试使用Database Designer来设计查询特定的投影,但这还不够。即使使用这些投影,简单的连接也需要大约14秒,这需要约1秒的预连接投影。

我的问题是:预连接投影是否正常这么慢地减缓数据插入,如果不是,那可能是罪魁祸首?如果这是正常的,那么它对我们来说是一个显示阻止,还有其他技术可以用来加速连接吗?

我们在5节点集群上运行Vertica,每个节点都有2 x四核CPU和32 GB内存。我的示例查询中的表分别有188,843,085和25,712,878行。

EXPLAIN输出如下所示:

EXPLAIN SELECT referer_via_.url as referralPageUrl, COUNT(DISTINCT sessio
n.id) as visits FROM owa_session as session JOIN owa_referer AS referer_vi
a_ ON session.referer_id = referer_via_.id WHERE session.yyyymmdd BETWEEN 
'20121123' AND '20121123' AND session.site_id = '49' GROUP BY referer_via_
.url  ORDER BY visits DESC LIMIT 250;

Access Path:
+-SELECT  LIMIT 250 [Cost: 1M, Rows: 250 (STALE STATISTICS)] (PATH ID: 0)
|  Output Only: 250 tuples
|  Execute on: Query Initiator
| +---> SORT [Cost: 1M, Rows: 1 (STALE STATISTICS)] (PATH ID: 1)
| |      Order: count(DISTINCT "session".id) DESC
| |      Output Only: 250 tuples
| |      Execute on: All Nodes
| | +---> GROUPBY PIPELINED (RESEGMENT GROUPS) [Cost: 1M, Rows: 1 (STALE 
STATISTICS)] (PATH ID: 2)
| | |      Aggregates: count(DISTINCT "session".id)
| | |      Group By: referer_via_.url
| | |      Execute on: All Nodes
| | | +---> GROUPBY HASH (SORT OUTPUT) (RESEGMENT GROUPS) [Cost: 1M, Rows
: 1 (STALE STATISTICS)] (PATH ID: 3)
| | | |      Group By: referer_via_.url, "session".id
| | | |      Execute on: All Nodes
| | | | +---> JOIN HASH [Cost: 1M, Rows: 1 (STALE STATISTICS)] (PATH ID: 
4) Outer (RESEGMENT)
| | | | |      Join Cond: ("session".referer_id = referer_via_.id)
| | | | |      Execute on: All Nodes
| | | | | +-- Outer -> STORAGE ACCESS for session [Cost: 463, Rows: 1 (ST
ALE STATISTICS)] (PUSHED GROUPING) (PATH ID: 5)
| | | | | |      Projection: public.owa_session_projection
| | | | | |      Materialize: "session".id, "session".referer_id
| | | | | |      Filter: ("session".site_id = '49')
| | | | | |      Filter: (("session".yyyymmdd >= 20121123) AND ("session"
.yyyymmdd <= 20121123))
| | | | | |      Execute on: All Nodes
| | | | | +-- Inner -> STORAGE ACCESS for referer_via_ [Cost: 293K, Rows:
26M] (PATH ID: 6)
| | | | | |      Projection: public.owa_referer_DBD_1_seg_Potency_2012112
2_Potency_20121122
| | | | | |      Materialize: referer_via_.id, referer_via_.url
| | | | | |      Execute on: All Nodes

5 个答案:

答案 0 :(得分:2)

加速加入:

  • 将会话表设置为在列&#34; yyyymmdd&#34;上进行分区。这将启用分区修剪

  • 在列上添加条件&#34; yyyymmdd&#34;至_referer_via_并在其上进行分区,如果可能的话(很可能不是)

  • 在会话的使用(超级)投影中按列表开头排列尽可能的列site_id

    • 将两个表分别在referer_id和id上进行细分。

在群集中拥有更多节点会有所帮助。

答案 1 :(得分:0)

  

我的问题是:预连接投影是否正常这么慢地减缓数据插入,如果不是,那可能是罪魁祸首?如果这是正常的,那么它对我们来说是一个显示阻止,还有其他技术可以用来加速连接吗?

我想受影响的数量会因您使用的数据集和结构而异。但是,由于这是您更改的变量,我相信可以肯定地说,预连接投影会导致缓慢。您将以插入时间为代价获得查询时间。

如果以下任何一种情况出错,请有人纠正我。我是通过记忆和通过与他人交谈获得的信息来进行的。

您可以通过几种方式在没有预连接投影的情况下加快连接速度。在这种情况下,引荐者ID。我相信如果你使用有助于的连接谓词来分割两个表的预测。您可以采取任何措施来过滤数据。

查看您的解释计划,您正在进行散列连接而不是合并连接,您可能希望查看它。

最后,我想通过解释计划或系统表了解您的查询是否实际使用了Database Designer推荐的投影。如果没有,请在查询中明确指定它们,看看是否有帮助。

答案 2 :(得分:0)

你似乎有很多STALE STATISTICS。 Responding对STALE统计数据非常重要。因为这就是你的查询速度慢的原因。如果没有关于底层数据的统计信息,Vertica的查询优化器无法选择最佳执行计划。并且响应STALE统计信息只会提高SELECT性能而不是更新性能。

如果您经常更新表格,请记住在VERTICA中您还需要考虑其他事项。请检查我发布到此question的答案。 我希望这应该有助于提高您的更新速度。

按照该答案中的说明探索AHM设置。如果您以后不需要在表格中选择已删除的行,那么通常不要让它们保留。有办法只保留最新的epoch版本的数据。或者手动清除已删除的数据。 让我知道它是怎么回事。

答案 3 :(得分:0)

我认为你的查询可以使用更多的显式。也不要使用Devil BETWEEN试试这个:

EXPLAIN SELECT 
    referer_via_.url as referralPageUrl, 
    COUNT(DISTINCT session.id) as visits 
FROM owa_session as session 
JOIN owa_referer AS referer_via_ 
    ON session.referer_id = referer_via_.id
WHERE session.yyyymmdd <= '20121123' 
AND session.yyyymmdd > '20121123' 
AND session.site_id = '49' 
GROUP BY referer_via_.url
-- this `visits` column needs a table name
ORDER BY visits DESC LIMIT 250;

我会说我真的很困惑,为什么你会使用同一DATEBETWEEN可能想要研究它。

答案 4 :(得分:0)

我的观点来自于使用列数据库的学术背景,包括Vertica(最近在数据库系统中获得博士学位)。

  

块引用   我的问题是:预连接预测是否正常减慢数据插入这一点,如果不是,那可能是罪魁祸首?如果这是正常的,那么它对我们来说是一个显示阻止,是否有其他技术可以用来加速连接?   块引用

是的,更新预测非常缓慢,理想情况下,您应该只在大批量中进行,以分摊更新成本。根本原因是每个投影代表数据的另一个副本(每个表格列是投影的一部分)。

单行插入需要向投影中的每列添加一个值(一个属性)。例如,具有20个属性的表中的单行插入需要至少20个列更新。更糟糕的是,每列都要进行排序和压缩。这意味着在列中插入新值需要对大块数据进行多次操作:读取数据/解压缩/更新/排序/压缩数据/写入数据。 Vertica有几个更新优化,但无法完全隐藏成本。

可以认为预测相当于传统行存储(MySQL,PostgreSQL,Oracle等)中的多列索引。预测与传统B-Tree索引的优势在于,读取它们(使用它们来回答查询)比使用传统索引要快得多。原因很多:不需要像非聚集索引那样访问头数据,由于压缩而需要更小的尺寸等。另一方面,它们更难以更新。权衡...