我正在调整网络分析工具以使用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
答案 0 :(得分:2)
加速加入:
将会话表设置为在列&#34; yyyymmdd&#34;上进行分区。这将启用分区修剪
在列上添加条件&#34; yyyymmdd&#34;至_referer_via_并在其上进行分区,如果可能的话(很可能不是)
在会话的使用(超级)投影中按列表开头排列尽可能的列site_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;
我会说我真的很困惑,为什么你会使用同一DATE
和BETWEEN
可能想要研究它。
答案 4 :(得分:0)
我的观点来自于使用列数据库的学术背景,包括Vertica(最近在数据库系统中获得博士学位)。
块引用 我的问题是:预连接预测是否正常减慢数据插入这一点,如果不是,那可能是罪魁祸首?如果这是正常的,那么它对我们来说是一个显示阻止,是否有其他技术可以用来加速连接? 块引用
是的,更新预测非常缓慢,理想情况下,您应该只在大批量中进行,以分摊更新成本。根本原因是每个投影代表数据的另一个副本(每个表格列是投影的一部分)。
单行插入需要向投影中的每列添加一个值(一个属性)。例如,具有20个属性的表中的单行插入需要至少20个列更新。更糟糕的是,每列都要进行排序和压缩。这意味着在列中插入新值需要对大块数据进行多次操作:读取数据/解压缩/更新/排序/压缩数据/写入数据。 Vertica有几个更新优化,但无法完全隐藏成本。
可以认为预测相当于传统行存储(MySQL,PostgreSQL,Oracle等)中的多列索引。预测与传统B-Tree索引的优势在于,读取它们(使用它们来回答查询)比使用传统索引要快得多。原因很多:不需要像非聚集索引那样访问头数据,由于压缩而需要更小的尺寸等。另一方面,它们更难以更新。权衡...