16

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

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

因此,我放弃了所有预加入投影并尝试使用数据库设计器来设计查询特定的投影,但这还不够。即使使用这些投影,一个简单的连接也需要约 14 秒,而使用预连接投影则需要约 1 秒。

我的问题是:预加入投影会减慢数据插入速度是否正常,如果不是,那么罪魁祸首可能是什么?如果它是正常的,那么它对我们来说就是一个阻碍,我们可以使用其他技术来加速连接吗?

我们在一个 5 节点集群上运行 Vertica,每个节点都有 2 个四核 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
4

5 回答 5

2

要加速加入:

  • 将会话表设计为在“yyyymmdd”列上进行分区。这将启用分区修剪

  • 将列“yyyymmdd”的条件添加到 _referer_via_ 并对其进行分区,如果可能的话(很可能不是)

  • 在会话的已用(超级)投影中,列 site_id 尽可能接近按列表排序的开头

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

在集群中拥有更多节点确实有帮助。

于 2014-12-26T21:38:59.057 回答
0

我的问题是:预加入投影会减慢数据插入速度是否正常,如果不是,那么罪魁祸首可能是什么?如果它是正常的,那么它对我们来说就是一个阻碍,我们可以使用其他技术来加速连接吗?

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

如果以下任何一个错误,请有人纠正我。我是靠记忆和与他人交谈时获得的信息。

您可以通过几种方式在没有预连接投影的情况下加快连接速度。在这种情况下,推荐人 ID。我相信,如果您使用连接谓词对两个表的预测进行分段,这会有所帮助。您可以做任何事情来过滤数据。

查看您的解释计划,您正在执行哈希连接而不是合并连接,您可能想要查看它。

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

于 2012-11-26T16:54:18.007 回答
0

这是我的观点,来自使用列数据库的学术背景,包括 Vertica(数据库系统最近的博士毕业生)。

Blockquote 我的问题是:预连接投影会减慢数据插入速度是否正常,如果不是,那么罪魁祸首可能是什么?如果它是正常的,那么它对我们来说就是一个阻碍,我们可以使用其他技术来加速连接吗?块引用

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

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

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

于 2014-10-01T16:34:26.827 回答
0

我认为您的查询可以使用更多的明确性。也不要在BETWEEN 之间使用那个 Devil试试这个:

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可能想调查一下。

于 2014-06-28T06:57:33.963 回答
0

你似乎有很多陈旧的统计数据。 响应STALE 统计数据很重要。因为这就是您的查询缓慢的原因。如果没有有关基础数据的统计信息,Vertica 的查询优化器无法选择最佳执行计划。响应 STALE 统计信息只会提高 SELECT 性能而不是更新性能。

如果您定期更新表格,请记住在 VERTICA 中还需要考虑其他事项。请检查我发布到这个问题的答案。我希望这有助于提高您的更新速度。

如该答案中所述,探索 AHM 设置。如果您以后不需要在表中选择已删除的行,最好不要保留它们。有一些方法可以只保留最新版本的数据。或手动清除已删除的数据。让我知道事情的后续。

于 2013-06-20T22:06:55.583 回答