使用 Elastic Crunch Scaling 提高查询性能
您可以选择将节点添加到数据库中,以提高长时间运行的复杂分析查询的性能。添加节点有助于这些查询提高运行速度。
当子群集中的节点多于数据库中的分片时,多个节点将订阅每个分片。为使子群集中的所有节点都参与查询,Vertica 查询优化器会自动使用称为 Elastic Crunch Scaling (ECS) 的功能。此功能会将处理每个分片中的数据的责任分配给订阅它的各个节点。在查询期间,每个节点要处理的数据更少,通常可以更快地完成查询。
例如,假设三分片数据库中包含六节点子群集。在此子群集中,两个节点会订阅每个分片。执行某个查询时,Vertica 会为每个节点分配其订阅的分片中大约一半的数据。由于子群集中的所有节点都参与该查询,因此该查询通常比只有一半节点参与时完成的速度更快。
ECS 会让节点数多于分片的子群集表现得好像数据库中的分片计数更高。在三分片数据库中,六节点子群集表现得好像数据库将每个分片分成两半而具有六个分片。但是,使用 ECS 的效率不如拥有更多的分片计数。实际上,您会发现在三分片数据库中的六节点子群集的查询性能比六分片数据库中的六节点子群集稍慢。
您可以调用 RESHARD_DATABASE 来更改数据库中的分片数量。如果新的分片数大于或等于子群集中的节点数,则子群集不再使用 ECS。这通常会导致查询速度更快。但是,重新分片会导致编录大小以及最初与新分片定义不一致的存储容器更大。在重新对齐存储容器之前,查询必须筛选出存储容器中超出新分片边界的数据。这会为查询增加少许开销。有关详细信息,请参阅更改数据库中的分片数。
您可以通过查询 V_CATALOG.SESSION_SUBSCRIPTIONS 系统表并查找 is_collaborating 列为 TRUE 的节点来确定优化器何时在子群集中使用 ECS。节点计数小于或等于数据库中分片数的子群集只有参与节点。节点数多于数据库的分片计数的子群集会为“额外”的节点分配协作者角色。执行查询时,这两种类型的节点之间的差异并不重要。这两种类型仅与 Vertica 如何组织节点以执行启用 ECS 的查询有关。
此示例显示如何获取参与或协作解决当前会话查询的节点列表:
=> SELECT node_name, shard_name, is_collaborating, is_participating
FROM V_CATALOG.SESSION_SUBSCRIPTIONS
WHERE is_participating = TRUE OR is_collaborating = TRUE
ORDER BY shard_name, node_name;
node_name | shard_name | is_collaborating | is_participating
----------------------+-------------+------------------+------------------
v_verticadb_node0004 | replica | f | t
v_verticadb_node0005 | replica | f | t
v_verticadb_node0006 | replica | t | f
v_verticadb_node0007 | replica | f | t
v_verticadb_node0008 | replica | t | f
v_verticadb_node0009 | replica | t | f
v_verticadb_node0007 | segment0001 | f | t
v_verticadb_node0008 | segment0001 | t | f
v_verticadb_node0005 | segment0002 | f | t
v_verticadb_node0009 | segment0002 | t | f
v_verticadb_node0004 | segment0003 | f | t
v_verticadb_node0006 | segment0003 | t | f
(12 rows)
您可以看到节点 4、5 和 7 正在参与,而节点 6、8 和 9 正在协作。
通过查看查询的 EXPLAIN 计划,您还可以看到已启用 ECS。在启用 ECS 的查询计划的顶部,显示的语句是“此查询涉及非参与节点 (this query involves non-participating nodes)”。这些非参与节点是协作节点,后者会使用参与节点来拆分分片中的数据。该计划还列出了参与查询的节点。
此示例显示三分片数据库的六节点子群集中已启用 ECS 的查询的说明计划:
=> EXPLAIN SELECT sales_quantity, sales_dollar_amount, transaction_type, cc_name
FROM online_sales.online_sales_fact
INNER JOIN online_sales.call_center_dimension
ON (online_sales.online_sales_fact.call_center_key
= online_sales.call_center_dimension.call_center_key
AND sale_date_key = 156)
ORDER BY sales_dollar_amount DESC;
QUERY PLAN
--------------------------------------------------------------------------------
------------------------------
QUERY PLAN DESCRIPTION:
The execution of this query involves non-participating nodes. Crunch scaling
strategy preserves data segmentation
------------------------------
EXPLAIN SELECT sales_quantity, sales_dollar_amount, transaction_type, cc_name
FROM online_sales.online_sales_fact
INNER JOIN online_sales.call_center_dimension
ON (online_sales.online_sales_fact.call_center_key
= online_sales.call_center_dimension.call_center_key
AND sale_date_key = 156)
ORDER BY sales_dollar_amount DESC;
Access Path:
+-SORT [Cost: 6K, Rows: 754K] (PATH ID: 1)
| Order: online_sales_fact.sales_dollar_amount DESC
| Execute on: v_verticadb_node0007, v_verticadb_node0004, v_verticadb_node0005,
| v_verticadb_node0006, v_verticadb_node0008, v_verticadb_node0009
| +---> JOIN MERGEJOIN(inputs presorted) [Cost: 530, Rows: 754K (202 RLE)] (PATH ID: 2)
| | Join Cond: (online_sales_fact.call_center_key = call_center_dimension.call_center_key)
| | Materialize at Output: online_sales_fact.sales_quantity,
| | online_sales_fact.sales_dollar_amount, online_sales_fact.transaction_type
| | Execute on: v_verticadb_node0007, v_verticadb_node0004,
| | v_verticadb_node0005, v_verticadb_node0006, v_verticadb_node0008,
| | v_verticadb_node0009
| | +-- Outer -> STORAGE ACCESS for online_sales_fact [Cost: 13, Rows: 754K (202 RLE)] (PATH ID: 3)
| | | Projection: online_sales.online_sales_fact_DBD_18_seg_vmart_b0
| | | Materialize: online_sales_fact.call_center_key
| | | Filter: (online_sales_fact.sale_date_key = 156)
| | | Execute on: v_verticadb_node0007, v_verticadb_node0004,
| | | v_verticadb_node0005, v_verticadb_node0006, v_verticadb_node0008,
| | | v_verticadb_node0009
| | | Runtime Filter: (SIP1(MergeJoin): online_sales_fact.call_center_key)
| | +-- Inner -> STORAGE ACCESS for call_center_dimension [Cost: 17, Rows: 200] (PATH ID: 4)
| | | Projection: online_sales.call_center_dimension_DBD_16_seg_vmart_b0
| | | Materialize: call_center_dimension.call_center_key, call_center_dimension.cc_name
| | | Execute on: v_verticadb_node0007, v_verticadb_node0004,
v_verticadb_node0005, v_verticadb_node0006, v_verticadb_node0008,
v_verticadb_node0009
. . .
利用 ECS
要利用 ECS,请创建辅助子群集,其中节点数是数据库中分片数的倍数。例如,在 12 分片数据库中,创建包含的节点数为 12 的倍数的子群集,例如 24 或 36。节点数必须是分片数的倍数,才能将数据均匀分布在子群集中的节点上。有关详细信息,请参阅子群集。
注意
您可以向现有的辅助子群集添加更多节点,而不是创建新的子群集。只需确保子群集中的节点数是分片计数的倍数即可。创建子群集后,让用户连接到它并运行其分析查询。Vertica 会自动在子群集中启用 ECS,因为它包含的节点数多于数据库中的分片数。
优化器如何将数据责任分配给节点
在订阅节点之间划分分片中的数据时,优化器有两种策略可供选择。一种策略针对使用数据分段的查询进行优化。包含 JOIN 或 GROUP BY 子句的查询依赖于数据分段。另一种策略针对不需要分段的查询。
默认情况下,优化器会自动选择要使用的策略。对于大多数查询,自动选择的策略会提高查询速度。对于某些查询,您可能希望使用提示来手动覆盖策略。在少量查询中,ECS 对性能没有帮助。在这些情况下,您可以禁用 ECS。有关详细信息,请参阅手动选择 ECS 策略。