这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
扩展 Eon 模式数据库
Eon 模式数据库的优势之一是它能够增大或缩小以满足您的工作负载需求。您可以在数据库中添加和移除节点以满足不断变化的工作负载需求。有关扩展数据库的原因以及它影响查询的方式的概述,请参阅弹性。
通过启动停止的节点来扩展数据库
扩展数据库的最简单方法是启动任何停止的节点:
通过添加节点来扩展数据库
如果您的数据库中没有停止的节点,或者停止的节点不在您要添加新节点的子群集中,则可以将新节点添加到数据库中。在受支持的环境中,使用 MC 只需一步便可配置新节点并将其添加到您的数据库中。有关详细信息,请参阅查看和管理您的群集。
您还可以手动添加新节点:
控制 Vertica 使用新节点的方式
新节点可以通过以下两种方式之一提高数据库的性能:
-
增加查询吞吐量(数据库同时处理的查询数量)。
-
提高单个查询性能(每个查询的运行速度)。
有关这些性能改进的详细信息,请参阅弹性。您可以通过选择将新节点添加到哪些子群集来控制新节点提高数据库性能的方式。以下主题说明如何使用扩展来提高吞吐量和查询性能。
1 - 更改数据库中的分片数
创建数据库时会设置初始分片数。出于以下原因,您可能会选择更改数据库中的分片数:
-
提高大型子群集的性能。例如,如果您有一个包含 6 个分片的 24 节点子群集,则该子群集使用 Elastic Crunch Scaling (ECS) 将处理每个分片中数据的责任分配给各个节点。将数据库重新分片为 24 个分片消除了 ECS 的必要性并提高了性能,因为 ECS 不如一比一的分片与节点比率那样高效。有关详细信息,请参阅使用 Elastic Crunch Scaling 提高查询性能。
-
减小编录大小。如果您的编录大小由于数据库中的大量分片而增加,您可能选择减少分片的数量。
-
从企业模式迁移到 Eon 模式后提高性能。当您将数据库从企业模式迁移到 Eon 模式时,Eon 数据库中的分片数最初设置为您在企业数据库中拥有的节点数。这个默认的分片数量可能并不理想。有关详细信息,请参阅选择分片数和初始节点数。
-
有效扩展您的数据库。为了在节点之间平均分配工作,数据库中的节点数量应当是分片数量的倍数或除数。如果您打算将子群集扩展到与本指南不兼容的大小,您可能需要将数据库重新分片。例如,对于有七个分片的数据库,其中的子群集包含的节点数必须为七的倍数。选择具有更多除数(例如 8 个)的分片数,可以让您在选择子群集中的节点数时具有更大的灵活性。
每次扩展子群集时,不应当将数据库重新分片。在重新分片过程中,可能会影响数据库的性能。重新分片后,子群集上的存储容器不会立即与新的分片订阅边界对齐。这种错位增加了查询执行的开销。
将 Eon 模式数据库重新分片
要将数据库重新分片,请使用新的分片计数作为实参调用 RESHARD_DATABASE 函数。此函数采用全局编录锁,因此请避免在繁忙时段或执行繁重的 ETL 负载时运行它。运行时取决于编录的大小。
RESHARD_DATABASE 完成后,群集中的节点使用新的编录分片定义。但是,重新分片过程不会立即更改公共存储中的存储容器。分片继续指向现有的存储容器。例如,如果您将数据库中的分片数量加倍,则每个存储容器现在有两个关联的分片。在查询期间,每个节点都会筛选掉存储容器中不适用于其订阅分片的数据。这为查询添加了少许开销。最终,Tuple Mover 的后台反身合并进程会自动更新存储容器,以便它们与新的分片定义保持一致。您可以调用 DO_TM_TASK 来运行让 Tuple Mover 立即重新对齐存储容器的 'RESHARDMERGEOUT' 任务。
以下查询返回 Tuple Mover 尚未重新对齐的任何存储容器的详细信息:
=> SELECT * FROM storage_containers WHERE original_segment_lower_bound IS NULL AND original_segment_upper_bound IS NULL;
示例
此示例演示了重新分片过程以及它如何影响分片分配和存储容器。为了说明重新分片的影响,我们比较了重新分片前后的分片分配和存储容器详细信息。以下三个查询返回有关数据库分片、节点订阅和存储容器编录对象的信息:
=> SELECT shard_name, lower_hash_bound, upper_hash_bound FROM shards ORDER BY shard_name;
shard_name | lower_hash_bound | upper_hash_bound
------------+------------------+------------------
replica | |
segment0001 | 0 | 1073741825
segment0002 | 1073741826 | 2147483649
segment0003 | 2147483650 | 3221225473
segment0004 | 3221225474 | 4294967295
(5 rows)
=> SELECT node_name, shard_name, is_primary, is_resubscribing, is_participating_primary FROM node_subscriptions;
node_name | shard_name | is_primary | is_resubscribing | is_participating_primary
----------+-------------+------------+------------------+--------------------------
initiator | replica | t | f | t
e0 | replica | f | f | t
e1 | replica | f | f | t
e2 | replica | f | f | t
e0 | segment0002 | t | f | t
e1 | segment0003 | t | f | t
e2 | segment0004 | t | f | t
initiator | segment0001 | t | f | t
(8 rows)
=> SELECT node_name, projection_name, storage_oid, sal_storage_id, total_row_count, deleted_row_count, segment_lower_bound, segment_upper_bound, shard_name FROM storage_containers WHERE projection_name = 't_super';
node_name | projection_name | storage_oid | sal_storage_id | total_row_count | deleted_row_count | segment_lower_bound | segment_upper_bound | shard_name
----------+-----------------+-------------------+--------------------------------------------------+-----------------+-------------------+---------------------+---------------------+-------------
initiator | t_super | 45035996273842990 | 022e836bff54b0aed318df2fe73b5afe00a0000000021b2d | 4 | 0 | 0 | 1073741825 | segment0001
e0 | t_super | 49539595901213486 | 024bbf043c1ca3f5c7a86a423fc7e1e300b0000000021b2d | 3 | 0 | 1073741826 | 2147483649 | segment0002
e1 | t_super | 54043195528583990 | 02dac7dc405a1620c92bae1a17c7bbad00c0000000021b35 | 8 | 0 | 2147483650 | 3221225473 | segment0003
e2 | t_super | 54043195528583992 | 02dac7dc405a1620c92bae1a17c7bbad00c0000000021b31 | 6 | 0 | 3221225474 | 4294967295 | segment0004
(4 rows)
以下对 RESHARD_DATABASE 的调用将分片数更改为八个:
=> SELECT RESHARD_DATABASE(8);
RESHARD_DATABASE
----------------------------------------------------------
The database has been re-sharded from 4 shards to 8 shards
(1 row)
可以使用以下查询来查看数据库的新分片定义:
=> SELECT shard_name, lower_hash_bound, upper_hash_bound FROM shards ORDER BY shard_name;
shard_name | lower_hash_bound | upper_hash_bound
-------------+------------------+------------------
replica | |
segment0001 | 0 | 536870913
segment0002 | 536870914 | 1073741825
segment0003 | 1073741826 | 1610612737
segment0004 | 1610612738 | 2147483649
segment0005 | 2147483650 | 2684354561
segment0006 | 2684354562 | 3221225473
segment0007 | 3221225474 | 3758096385
segment0008 | 3758096386 | 4294967295
(9 rows)
数据库现在有八个分片。因为重新分片将每个分片的边界范围减半,所以每个分片负责大约一半的公共存储数据。
以下查询返回数据库的新节点订阅:
=> SELECT node_name, shard_name, is_primary, is_resubscribing, is_participating_primary FROM node_subscriptions;
node_name | shard_name | is_primary | is_resubscribing | is_participating_primary
-----------+-------------+------------+------------------+--------------------------
initiator | replica | t | f | t
e0 | replica | f | f | t
e1 | replica | f | f | t
e2 | replica | f | f | t
initiator | segment0001 | t | f | t
e0 | segment0002 | t | f | t
e1 | segment0003 | t | f | t
e2 | segment0004 | t | f | t
initiator | segment0005 | t | f | t
e0 | segment0006 | t | f | t
e1 | segment0007 | t | f | t
e2 | segment0008 | t | f | t
(12 rows)
重新分片后,每个节点现在订阅两个分片而不是一个。
可以使用以下查询来查看重新分片如何影响数据库的存储容器编录对象:
=> SELECT node_name, projection_name, storage_oid, sal_storage_id, total_row_count, deleted_row_count, segment_lower_bound, segment_upper_bound, shard_name FROM storage_containers WHERE projection_name = 't_super';
node_name | projection_name | storage_oid | sal_storage_id | total_row_count | deleted_row_count | segment_lower_bound | segment_upper_bound | shard_name
----------+-----------------+-------------------+--------------------------------------------------+-----------------+-------------------+---------------------+---------------------+-------------
initiator | t_super | 45035996273843145 | 02dac7dc405a1620c92bae1a17c7bbad00c0000000021b35 | 8 | 0 | 2147483650 | 3221225473 | segment0005
initiator | t_super | 45035996273843149 | 022e836bff54b0aed318df2fe73b5afe00a0000000021b2d | 4 | 0 | 0 | 1073741825 | segment0001
e0 | t_super | 49539595901213641 | 02dac7dc405a1620c92bae1a17c7bbad00c0000000021b35 | 8 | 0 | 2147483650 | 3221225473 | segment0006
e0 | t_super | 49539595901213645 | 022e836bff54b0aed318df2fe73b5afe00a0000000021b2d | 4 | 0 | 0 | 1073741825 | segment0002
e1 | t_super | 54043195528584141 | 02dac7dc405a1620c92bae1a17c7bbad00c0000000021b31 | 6 | 0 | 3221225474 | 4294967295 | segment0007
e1 | t_super | 54043195528584143 | 02dac7dc405a1620c92bae1a17c7bbad00c0000000021b31 | 6 | 0 | 1073741826 | 2147483649 | segment0003
e2 | t_super | 54043195528584137 | 024bbf043c1ca3f5c7a86a423fc7e1e300b0000000021b2d | 3 | 0 | 3221225474 | 4294967295 | segment0008
e2 | t_super | 54043195528584139 | 024bbf043c1ca3f5c7a86a423fc7e1e300b0000000021b2d | 3 | 0 | 1073741826 | 2147483649 | segment0004
(8 rows)
分片指向与重新分片之前具有相同 sal_storage_id
的存储文件。最终,TM 的合并进程将自动更新存储容器。
将数据库重新分片后,您可以查询 DC_ROSES_CREATED 表以跟踪原始 ROS 容器和派生新存储容器的 DVMiniROS:
=> SELECT node_name, projection_name storage_oid, old_storage_oid, is_dv FROM DC_ROSES_CREATED;
node_name | projection_name | storage_oid | old_storage_oid | is_dv
---------------------+------------------+-------------------+-----------------------------
initiator | t_super | 45035996273860625 | 45035996273843149 | f
initiator | t_super | 45035996273860632 | 0 | f
e0 | t_super | 45035996273843149 | 0 | f
(3 rows)
2 - 使用子群集提高查询吞吐量
提高查询吞吐量会同时增加 Eon 模式数据库处理的查询数量。当您的工作负载包含多个短期运行的查询时,您通常会担心数据库的吞吐量。它们通常被称为“仪表板查询”。该术语描述了当大量用户打开基于 Web 的仪表板页面以监控某种状态时您看到的工作负载类型。这些仪表板往往会频繁更新,使用较简单的短期运行的查询,而不是分析量繁重的长期运行查询。
提高数据库吞吐量的最佳方法是向数据库添加新的子群集或启动任何停止的子群集。然后使用连接负载均衡策略在这些子群集之间分配客户端连接。子群集独立处理查询。通过添加更多子群集,您可以提高数据库的并行度。
为获得最佳性能,应使子群集中的节点数与数据库中的分片数相同。如果您选择的节点数少于分片数,请将节点数设为分片数的偶数除数。当分片数可以被节点数整除时,数据库中的数据就会在子群集中的节点之间平均分配。
添加子群集的最简单方法是使用 MC:
-
在 MC 主页中,单击要将子群集添加到的数据库。
-
单击管理 (Manage)。
-
单击添加子群集 (Add Subcluster)。
-
按照向导中的步骤添加子群集。通常,您需要填写的唯一项目是子群集名称和要添加到其中的实例数。
注意
MC 目前不支持在所有平台上创建实例。对于 MC 不支持实例的平台,您可以手动添加子群集。有关详细信息,请参阅
创建子群集。
在吞吐量子群集之间分配客户端
要从添加的子群集中获益,您必须让执行短期查询的客户端连接到子群集包含的节点。查询仅在包含启动程序节点(客户端连接到的节点)的子群集上运行。使用连接负载均衡策略将连接分布在您创建的所有子群集中,以提高查询吞吐量。有关详细信息,请参阅连接负载均衡策略。
以下示例创建了一个负载均衡策略,该策略将客户端连接分布在两个名为 query_pool_a 和 query_pool_b 的三节点子群集中。此示例:
-
在两个子群集中的六个节点上创建网络地址。
-
从两个子群集中的所有节点创建一个负载均衡组。
-
创建路由规则以将所有传入连接重定向到两个子群集。
=> CREATE NETWORK ADDRESS node04 ON v_verticadb_node0004 WITH '203.0.113.1';
CREATE NETWORK ADDRESS
=> CREATE NETWORK ADDRESS node05 ON v_verticadb_node0005 WITH '203.0.113.2';
CREATE NETWORK ADDRESS
=> CREATE NETWORK ADDRESS node06 ON v_verticadb_node0006 WITH '203.0.113.3';
CREATE NETWORK ADDRESS
=> CREATE NETWORK ADDRESS node07 ON v_verticadb_node0007 WITH '203.0.113.4';
CREATE NETWORK ADDRESS
=> CREATE NETWORK ADDRESS node08 ON v_verticadb_node0008 WITH '203.0.113.5';
CREATE NETWORK ADDRESS
=> CREATE NETWORK ADDRESS node09 ON v_verticadb_node0009 WITH '203.0.113.6';
CREATE NETWORK ADDRESS
=> CREATE LOAD BALANCE GROUP query_subclusters WITH SUBCLUSTER query_pool_a,
query_pool_b FILTER '0.0.0.0/0';
CREATE LOAD BALANCE GROUP
=> CREATE ROUTING RULE query_clients ROUTE '0.0.0.0/0' TO query_subclusters;
CREATE ROUTING RULE
重要
在将要从专用网络外部连接客户端的云环境中,在创建网络地址时对每个节点使用外部 IP 地址。否则,外部客户端将无法连接到节点。
如果您同时拥有内部和外部客户端,请为每个节点设置两个网络地址,并将它们添加到两个单独的负载均衡组:一个用于内部客户端,另一个用于外部客户端。然后创建两个路由规则,一个将内部客户端路由到内部组,另一个将外部客户端路由到外部组。使内部客户端的路由规则仅应用于您的内部客户端将从其中连接的虚拟专用网络(例如,10.0.0.0/8)。外部客户端的路由规则可以使用 0.0.0.0/0 CIDR 范围(所有 IP 地址)作为传入连接地址范围。这些规则将一起正常工作,因为更具体的内部客户端路由规则优先于限制较少的外部客户端规则。
创建策略后,任何选择负载均衡的客户端都将重定向到两个子群集中的节点之一。例如,当您使用带有 -C 标志的 vsql 连接到群集中的节点 1(IP 地址为 203.0.113.1)时,您会看到类似如下的输出:
$ vsql -h 203.0.113.1 -U dbadmin -w mypassword -C
Welcome to vsql, the Vertica Analytic Database interactive terminal.
Type: \h or \? for help with vsql commands
\g or terminate with semicolon to execute query
\q to quit
SSL connection (cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, protocol: TLSv1.2)
INFO: Connected using a load-balanced connection.
INFO: Connected to 203.0.113.7 at port 5433.
=>
连接负载均衡策略考虑了在选择节点来处理客户端连接时停止的节点。如果您在低需求期间关闭一个或多个子群集以节省资金,那么只要某些节点仍处于运行状态,您就无需调整负载均衡策略。
3 - 使用 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 策略。
4 - 手动选择 ECS 策略
当子群集中的节点数大于数据库分片数时,Vertica 查询优化器使用 elastic crunch scaling (ECS) 让所有节点参与处理查询。对于每个分片,优化器使用以下策略之一在其订阅节点之间划分处理分片数据的责任:
优化器会根据查询是否可以利用数据分段而自动选择策略。您可以使用 EXPLAIN 来判断优化器为查询选择的策略。计划解释的顶部说明了 ECS 是否保留分段。例如,这个针对单表的简单查询不需要使用分段,所以使用了 I/O 优化策略:
=> EXPLAIN SELECT employee_last_name,
employee_first_name,employee_age
FROM employee_dimension
ORDER BY employee_age DESC;
QUERY PLAN
--------------------------------------------------------------------------------
------------------------------
QUERY PLAN DESCRIPTION:
The execution of this query involves non-participating nodes.
Crunch scaling strategy does not preserve data segmentation
------------------------------
. . .
对于使用 JOIN 的较复杂查询,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
------------------------------
. . .
在大多数情况下,优化器选择最佳策略来在订阅同一分片的节点之间拆分数据。但是,您可能偶尔发现某些查询性能不佳。在这些情况下,查询可以嵌入 ECSMODE 提示来指定使用哪种策略甚至禁用 ECS。
为单个查询设置 ECS 策略
您可以在查询中使用 ECSMODE 提示来强制优化器使用特定的 ECS 策略(或完全禁用 ECS)。ECSMODE 提示采用以下实参之一:
-
AUTO
:优化器选择要使用的策略,仅当在会话级别设置 ECS 模式时才有用(请参阅为会话或数据库设置 ECS 策略)。
-
IO_OPTIMIZED
:使用 I/O 优化策略。
-
COMPUTE_OPTIMIZED
:使用计算优化策略。
-
NONE
:对此查询禁用 ECS。只有参与节点才会涉及查询执行;协作节点不会涉及。
以下示例显示了简单的单表查询(被强制使用计算优化策略)的查询计划:
=> EXPLAIN SELECT /*+ECSMode(COMPUTE_OPTIMIZED)*/ employee_last_name,
employee_first_name,employee_age
FROM employee_dimension
ORDER BY employee_age DESC;
QUERY PLAN
--------------------------------------------------------------------------------
------------------------------
QUERY PLAN DESCRIPTION:
The execution of this query involves non-participating nodes.
Crunch scaling strategy preserves data segmentation
------------------------------
. . .
此示例在三分片数据库的六节点群集中禁用 ECS:
=> EXPLAIN SELECT /*+ECSMode(NONE)*/ employee_last_name,
employee_first_name,employee_age
FROM employee_dimension
ORDER BY employee_age DESC;
QUERY PLAN
--------------------------------------------------------------------------------
------------------------------
QUERY PLAN DESCRIPTION:
------------------------------
EXPLAIN SELECT /*+ECSMode(NONE)*/ employee_last_name,
employee_first_name,employee_age
FROM employee_dimension
ORDER BY employee_age DESC;
Access Path:
+-SORT [Cost: 243, Rows: 10K] (PATH ID: 1)
| Order: employee_dimension.employee_age DESC
| Execute on: v_verticadb_node0007, v_verticadb_node0004, v_verticadb_node0005
| +---> STORAGE ACCESS for employee_dimension [Cost: 71, Rows: 10K] (PATH ID: 2)
| | Projection: public.employee_dimension_DBD_8_seg_vmart_b0
| | Materialize: employee_dimension.employee_first_name,
| | employee_dimension.employee_last_name, employee_dimension.employee_age
| | Execute on: v_verticadb_node0007, v_verticadb_node0004,
| | v_verticadb_node0005
. . .
注意,该查询计划缺少“此查询涉及非参与节点 (this query involves non-participating nodes)”说明,这表示它不使用 ECS。另外,它仅列出了三个参与节点。这些节点被标记为参与 V_CATALOG.SESSION_SUBSCRIPTIONS 系统表。
为会话或数据库设置 ECS 策略
您可以使用 ECSMode 配置参数来设置当前会话的 ECS 策略。此参数接受与 ECSMODE 提示相同的值,NONE 除外(该值仅对单个查询有效)。
以下示例演示如何使用配置参数强制简单查询使用 COMPUTE_OPTIMIZED 策略。然后,它将参数设置回其默认值 AUTO:
=> EXPLAIN SELECT employee_first_name,employee_age
FROM employee_dimension ORDER BY employee_age DESC;
QUERY PLAN
--------------------------------------------------------------------------------
------------------------------
QUERY PLAN DESCRIPTION:
The execution of this query involves non-participating nodes.
Crunch scaling strategy does not preserve data segmentation
------------------------------
. . .
=> ALTER SESSION SET ECSMode = 'COMPUTE_OPTIMIZED';
ALTER SESSION
=> EXPLAIN SELECT employee_first_name,employee_age
FROM employee_dimension ORDER BY employee_age DESC;
QUERY PLAN
--------------------------------------------------------------------------------
------------------------------
QUERY PLAN DESCRIPTION:
The execution of this query involves non-participating nodes.
Crunch scaling strategy preserves data segmentation
------------------------------
. . .
=> ALTER SESSION SET ECSMode = 'AUTO';
ALTER SESSION
单个查询提示会覆盖会话级别设置。此示例将会话默认设置为使用 COMPUTE_OPTIMIZED,然后使用值为 AUTO 的 ECSMode 提示还原查询的默认行为:
=> ALTER SESSION SET ECSMode = 'COMPUTE_OPTIMIZED';
ALTER SESSION
=> EXPLAIN SELECT /*+ECSMode(AUTO)*/ employee_first_name,employee_age
FROM employee_dimension ORDER BY employee_age DESC;
QUERY PLAN
-----------------------------------------------------------------------------
------------------------------
QUERY PLAN DESCRIPTION:
The execution of this query involves non-participating nodes.
Crunch scaling strategy does not preserve data segmentation
------------------------------
请注意,将 ECSMode 提示设置为 AUTO 会让优化器选择 I/O 优化策略(不保留分段),而不是使用在会话级别设置的计算优化策略。
您还可以使用 ALTER DATABASE 在数据库级别设置 ECS 策略。但是,这样做会覆盖使用 ECS 的所有子群集中所有用户的 Vertica 优化器设置。在数据库级别设置 ECS 策略之前,请验证启用 ECS 的子群集的所有用户运行的大多数查询是否必须覆盖优化器的默认行为。如果不是,则仅针对受益于特定策略的查询,使用会话或查询级别设置来覆盖优化器。