这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

文件导出

您可能希望从 Vertica 导出表或其他查询结果,以便与其他应用程序共享,或将较低优先级的数据从 ROS 移动到成本较低的存储。Vertica 支持针对不同文件格式的多种 EXPORT TO 语句:EXPORT TO PARQUETEXPORT TO ORCEXPORT TO JSONEXPORT TO DELIMITED

您可以将数据导出到 HDFS、S3、Google Cloud Storage (GCS)、Azure Blob Storage 或 Linux 文件系统。您可以导出 ROS 数据或可通过外部表读取的数据。导出 ROS 数据后,可以删除受影响的 ROS 分区以回收存储空间。

一定要避免同时导出到同一个输出目标。这样做在任何文件系统上都是错误的,并且会产生不正确的结果。

导出数据后,可以定义外部表以在 Vertica 中读取该数据。Parquet 和 ORC 是 Vertica 可以在查询优化中利用的列式格式,因此请考虑将其中一种格式用于外部表。请参阅使用外部数据

1 - 语法

使用 EXPORT 语句可导出由 SELECT 语句指定的数据,如以下示例所示:

=> EXPORT TO PARQUET(directory='webhdfs:///data/sales_data')
   AS SELECT * FROM public.sales;
 Rows Exported
---------------
         14336
(1 row)

directory 实参会指定写入文件的位置且为必需实参。您必须具有写入输出目录的权限。该目录不得已存在。您可以导出到 HDFS、S3、GCS、Azure 或 Linux 文件系统。有关特定于对象存储的其他注意事项,请参阅导出到对象存储。如果导出到本地 Linux 文件系统(不是共享的 NFS 挂载),则必须执行一些额外步骤;请参阅导出到 Linux 文件系统

可以使用 EXPORT 语句在 Vertica 中的多个表之间写入查询并导出结果。通过这种方法,可以利用 Vertica 中强大、快速的查询执行,同时将结果提供给其他客户端:

=> EXPORT TO ORC(directory='webhdfs:///data/sales_by_region')
   AS SELECT sale.price, sale.date, store.region
   FROM public.sales sale
   JOIN public.vendor store ON sale.distribID = store.ID;
 Rows Exported
---------------
         23301
(1 row)

数据类型

所有导出程序都可以导出标量类型和基元数组。JSON 导出程序还支持任意组合的 ARRAYROW 类型:

=> SELECT * FROM restaurants;
       name        | cuisine |       location_city        |                                     menu
-------------------+---------+----------------------------+------------------------------------------------------------------------------
 Bob's pizzeria    | Italian | ["Cambridge","Pittsburgh"] | [{"item":"cheese pizza","price":null},{"item":"spinach pizza","price":10.5}]
 Bakersfield Tacos | Mexican | ["Pittsburgh"]             | [{"item":"veggie taco","price":9.95},{"item":"steak taco","price":10.95}]
(2 rows)

=> EXPORT TO JSON (directory='/output/json') AS SELECT * FROM restaurants;
 Rows Exported
---------------
             2
(1 row)

=> \! cat /output/json/*.json
{"name":"Bob's pizzeria","cuisine":"Italian","location_city":["Cambridge","Pittsburgh"],"menu":[{"item":"cheese pizza","price":null},{"item":"spinach pizza","price":10.5}]}
{"name":"Bakersfield Tacos","cuisine":"Mexican","location_city":["Pittsburgh"],"menu":[{"item":"veggie taco","price":9.95},{"item":"steak taco","price":10.95}]}

查询

EXPORT 语句会重写您指定的查询,因为导出是由用户定义的转换函数 (UDTF) 完成的。由于进行了该重写,系统对您提供的查询会有一些限制。

查询只能包含一个外部 SELECT 语句。例如,您不能使用 UNION:

=> EXPORT TO PARQUET(directory = '/mnt/shared_nfs/accounts/rm')
   OVER(PARTITION BY hash)
   AS
   SELECT 1 as account_id, '{}' as json, 0 hash
   UNION ALL
   SELECT 2 as account_id, '{}' as json, 1 hash;
ERROR 8975:  Only a single outer SELECT statement is supported
HINT:  Please use a subquery for multiple outer SELECT statements

而需要重写查询以使用子查询:

=> EXPORT TO PARQUET(directory = '/mnt/shared_nfs/accounts/rm')
   OVER(PARTITION BY hash)
   AS
   SELECT
    account_id,
    json
   FROM
   (
     SELECT 1 as account_id, '{}' as json, 0 hash
     UNION ALL
     SELECT 2 as account_id, '{}' as json, 1 hash
   ) a;
 Rows Exported
---------------
             2
(1 row)

要使用 UNION、INTERSECT 和 EXCEPT 等复合语句,请将其重写为子查询。

导出数据时,可以使用 OVER() 子句对数据进行分区和排序,如对数据进行分区和排序中所述。分区和排序可以提高查询性能。如果对数据进行分区,则不能在 SELECT 语句中指定架构名称和表名称。在这种情况下,请仅指定列名称。

所有导出程序都有一个必需的 directory 参数。所有导出程序都允许您指定压缩类型,并且每个导出程序都有特定于格式的参数。请参阅各个参考页面上的参数描述:EXPORT TO PARQUETEXPORT TO ORCEXPORT TO JSONEXPORT TO DELIMITED

2 - 对数据进行分区和排序

导出时,您可以在 SELECT 语句中使用可选的 OVER 子句来指定如何对导出的数据进行分区和/或排序。当 Vertica 查询包含输出数据的外部表时,进行分区可减小输出数据文件的大小并提高性能。(请参阅分区文件路径。)如果未指定如何对数据进行分区,Vertica 会优化导出以实现最大并行度。

要指定分区列,请在 OVER 子句中使用 PARTITION BY,如以下示例所示:

=> EXPORT TO PARQUET(directory = 'webhdfs:///data/export')
  OVER(PARTITION BY date) AS SELECT transactionID, price FROM public.sales;
 Rows Exported
---------------
         28337
(1 row)

您既可以按某个列进行分区,也可以将该列包含在 SELECT 子句中。包含该列即可对其进行排序。Vertica 在查询执行期间仍会利用分区。

您可以对分区内的值进行排序以进一步提高性能。根据表列在查询谓词中出现的可能性对其进行排序;应先对在比较或范围谓词中最常出现的列进行排序。可以在 OVER 子句中使用 ORDER BY 对每个分区内的值进行排序:

=> EXPORT TO PARQUET(directory = 'webhdfs:///data/export')
  OVER(PARTITION BY date ORDER BY price) AS SELECT date, price FROM public.sales;
 Rows Exported
---------------
         28337
(1 row)

即使未进行分区,也可以使用 ORDER BY。按排序顺序存储数据可以提高数据访问速度和谓词评估性能。

OVER 子句中的目标必须为列引用,不能为表达式。有关 OVER 的详细信息,请参阅 SQL 分析

如果要将数据导出到本地文件系统,您可能需要强制要求一个节点写入所有文件。为此,请使用 OVER 空子句。

3 - 导出到对象存储

对象存储文件系统(S3、Google Cloud Storage 和 Azure Blob Storage)与影响数据导出的其他文件系统存在一些差异。您必须为身份验证和区域设置一些额外的配置参数,对输出也有一些限制。

在以下参考页面中,对 URI 格式和配置参数进行了描述:

配置参数影响对相应对象存储的所有访问,包括读取和写入。您可以通过在导出数据之前在会话级别进行设置来限制设置的效果,而不是全局设置它们。

输出限制

对象存储文件系统不支持就地重命名文件;它们将重命名实施为副本,然后删除。在其他文件系统上,EXPORT TO PARQUET 通过将输出写入临时目录并在完成时重命名来支持原子性。这种方法对于对象存储是不切实际的,因此 EXPORT TO PARQUET 直接写入目标路径。因此,可以在导出完成之前开始读取导出的数据,这可能会导致错误。请小心等待导出完成,然后再使用数据。

Vertica 不支持同时导出到对象存储中的同一路径。结果未进行定义。

S3 将存储桶限制为 5TB。您可能需要拆分非常大的导出内容。

4 - 导出到 Linux 文件系统

如果您导出到 Linux 文件系统上的 NFS 挂载位置,则导出器的行为方式与任何其他共享位置相同:所有导出的文件都写入同一个目标。

如果您导出到本地 Linux 文件系统,则每个 Vertica 节点都会将其部分导出内容写入其本地文件系统。要定义一个外部表来读取导出的数据,您必须指定每个节点和路径,如下例所示:

=> CREATE EXTERNAL TABLE sales (...)
   AS COPY FROM '/data/sales/*.parquet' ON node01,
                '/data/sales/*.parquet' ON node02,
                '/data/sales/*.parquet' ON node03 PARQUET;

每个节点上的路径与您在导出语句中指定的路径相同。

如果省略 ON 子句而只指定路径,则 COPY 仅加载它在启动程序节点上找到的数据。

5 - 监控导出

您可以查看有关导出的信息,包括行组数、文件大小和文件名。

导出语句为 UDx。UDX_EVENTS 系统表会记录在 UDx 执行期间记录的事件,包括时间戳、节点名称和会话 ID。此表包含一列 (RAW),其中含有单个 UDx 记录的任何其他数据的 VMap。导出语句会在此表中记录有关已导出文件的详细信息。虽然可以直接使用此表并实体化 VMap 列中的值,但您可能更愿意定义用于简化访问的视图。

以下语句定义的视图将仅显示 EXPORT TO PARQUET 中的事件,从而实体化 VMap 值。

=> CREATE VIEW parquet_export_events AS
   SELECT
    report_time,
    node_name,
    session_id,
    user_id,
    user_name,
    transaction_id,
    statement_id,
    request_id,
    udx_name,
    file,
    created,
    closed,
    rows,
    row_groups,
    size_mb
   FROM
    v_monitor.udx_events
   WHERE
    udx_name ilike 'ParquetExport%';

导出程序将报告以下特定于 UDx 的列:

以下示例显示了单次导出的结果。

=> SELECT file,rows,row_groups,size_mb FROM PARQUET_EXPORT_EVENTS;
                                  file                                 | rows  | row_groups | size_mb
-----------------------------------------------------------------------+-------+------------+----------
 /data/outgZxN3irt/450c4213-v_vmart_node0001-139770732459776-0.parquet | 29696 | 1          | 0.667203
 /data/outgZxN3irt/9df1c797-v_vmart_node0001-139770860660480-0.parquet | 29364 | 1          | 0.660922
(2 rows)

在此表中,输出目录名称 (/data/out) 后面附加了生成的字符串 (gZxN3irt)。要多次导出到 HDFS 或本地文件系统(包括 NFS),EXPORT TO PARQUET 会先将数据写入临时目录,然后在操作结束时对其重命名。系统会在导出期间记录事件,因此显示临时名称。某些输出目标(例如 AWS S3)不支持重命名操作,因此在这些情况下,此表不会显示生成的名称。