这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
文件导出
您可能希望从 Vertica 导出表或其他查询结果,以便与其他应用程序共享,或将较低优先级的数据从 ROS 移动到成本较低的存储。Vertica 支持针对不同文件格式的多种 EXPORT TO 语句:EXPORT TO PARQUET、EXPORT TO ORC、EXPORT TO JSON 和 EXPORT 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 导出程序还支持任意组合的 ARRAY 和 ROW 类型:
=> 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 PARQUET、EXPORT TO ORC、EXPORT TO JSON 和 EXPORT 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)不支持重命名操作,因此在这些情况下,此表不会显示生成的名称。