SELECT INTO
描述
该语句用于将查询结果存储在变量或文件中。其中:
-
SELECT ... INTO OUTFILE用于将结果集存储在外部文件,并可以指定输出格式。信息SELECT ... INTO OUTFILE输出数据时支持使用\N代表NULL。 -
SELECT ... INTO DUMPFILE用于向外部文件写入不带格式的单行。 -
SELECT ... INTO var_list用于将结果集存储到变量。
权限要求
执行 SELECT INTO 语句,需要拥有 FILE 权限和对应表的 SELECT 权限。有关 seekdb 权限的详细介绍,参见 seekdb 的 权限分类。
示例如下:
要为用户授予 FILE 权限,可以使用以下命令格式:
GRANT FILE ON *.* TO user_name;
其中,user_name 是需要执行 SELECT INTO 命令的用户。
语法
select_stmt
INTO {OUTFILE 'file_name' [PARTITION BY part_expr] [{CHARSET | CHARACTER SET} charset_name] [field_opt] [line_opt] [file_opt]
| OUTFILE 'file_name' [PARTITION BY part_expr] [FORMAT = (external_file_format_list)] [file_opt]
| DUMPFILE 'file_name'
| into_var_list};
field_opt:
{COLUMNS | FIELDS} field_term_list
field_term_list:
field_term [, field_term ...]
field_term:
{[OPTIONALLY] ENCLOSED | TERMINATED | ESCAPED} BY string
line_opt:
LINES line_term_list
line_term_list:
line_term [line_term]
line_term:
{STARTING | TERMINATED} BY string
file_opt:
file_option [, file_option ...]
file_option:
SINGLE [=] {TRUE | FALSE}
| MAX_FILE_SIZE [=] {int | string}
| BUFFER_SIZE [=] {int | string}
external_file_format_list:
type_csv_option
| type_parquet_option
| type_orc_option
type_csv_option:
TYPE = 'CSV'
LINE_DELIMITER = '<string>' | <expr>
FIELD_DELIMITER = '<string>' | <expr>
ESCAPE = '<character>' | <expr>
FIELD_OPTIONALLY_ENCLOSED_BY = '<character>' | <expr>
FIELD_ENCLOSED_BY = '<character>' | <expr>
ENCODING = 'charset'
COMPRESSION = [NONE, GZIP, DEFLATE, ZSTD] | '<string>'
FILE_EXTENSION = ['<string>']
type_parquet_option:
TYPE = 'PARQUET',
COMPRESSION = '<string>'
ROW_GROUP_SIZE = '<string>' | <int>
type_orc_option:
TYPE = 'ORC'
COMPRESSION = '<string>'
COMPRESSION_BLOCK_SIZE = '<string>' | <int>
STRIPE_SIZE = '<string>' | <int>
ROW_INDEX_STRIDE = <int>
参数解释
| 参数 | 描述 |
|---|---|
| select_stmt | 指定要执行的查询语句。select_stmt 必须返回一个结果集,查询语句的具体结构和选项信息,参见 SELECT。 说明 INTO 子句内容的位置也可以在查询语句的 FROM 之前。例如,SELECT * INTO OUTFILE '/home/admin/test_data/test_tbl1.csv' FROM test_tbl1 WHERE id > 5;。 |
| file_name | 用于指定导出文件的路径和文件名。详细介绍可参见下文 file_name。 |
| PARTITION BY part_expr | 说明 对于 seekdb 支持控制导出数据的分区方式。可选项,用于控制导出数据的分区方式, part_expr 的值作为导出路径的一部分,对每行数据计算 part_expr 的值,part_expr 取值相同的行属于同一个分区,将导出到同一个目录中。注意
|
| FORMAT = (external_file_format_list) | 可选项,FORMAT 子句用于指定导出文件格式相关的属性,使用 TYPE 指定导出 CSV、PARQUET、ORC 三种文件格式,TYPE 不能为空。详细介绍可参见下文 external_file_format_list。 |
| CHARSET | CHARACTER SET charset_name | 可选项,指定导出到外部文件的字符集。charset_name 表示字符集的名称。 |
| field_opt | 可选项,导出字段格式选项。指定输出文件中各个字段的格式,通过 FIELDS 或 COLUMNS 子句来指定。详细介绍可参见下文 field_term。 |
| line_opt | 可选项,导出数据行的开始和结束符选项。指定输出文件中每一行的开始和结束字符,通过 LINES 子句设置。详细介绍可参见下文 line_term。 |
| file_opt | 可选项,控制是否导出到多个文件和导出到多文件时单个文件的大小。详细介绍可参见下文 file_option。 |
file_name
file_name 有以下格式:
-
将导出文件保存在 seekdb 节点时,格式为:
/\$PATH/\$FILENAME,其中各参数解释如下:\$PATH:指定要保存导出文件的路径,即指定导出文件在 seekdb 节点的路径。\$FILENAME:指定要导出文件的名称。当SINGLE = FALSE时表示导出文件的前缀,不指定时会生成默认的前缀data,系统自动生成后缀。
-
将导出文件保存在 OSS 上时,格式为:
oss://\$PATH/\$FILENAME/?host=\$HOST&access_id=\$ACCESS_ID&access_key=\$ACCESSKEY,其中各参数解释如下:\$PATH:指定要保存导出文件的路径,即指定存储桶中的文件路径。\$FILENAME:指定要导出文件的名称。当SINGLE = FALSE时表示导出文件的前缀,不指定时会生成默认的前缀data,系统自动生成 后缀。\$HOST:指定 OSS 服务的主机名或 CDN 加速的域名,即要访问的 OSS 服务的地址。\$ACCESS_ID:指定访问 OSS 服务所需的 Access Key ID,用于身份验证。\$ACCESSKEY:指定了访问 OSS 服务所需的 Access Key Secret,用于身份验证。
信息- seekdb 中
SELECT INTO适配 S3 和基于 S3 协议的对象存储作为数据导出的目的端。 - 由于阿里云 OSS 有文件大小的限制,对于超过 5 GB 的文件,导出到 OSS 时会被拆分成多个文件,每个文件小于 5 GB。
field_term
[OPTIONALLY] ENCLOSED BY string:用来指定包裹字段值的符号,默认没有引用符号。例如,ENCLOSED BY '"'表示字符值放在双引号之间。如果使用了OPTIONALLY关键字,则仅对字符串类型的值使用指定字符包裹。TERMINATED BY string:用来指定字段值之间的符号。例如,TERMINATED BY ','指定了逗号作为两个字段值之间的标志。ESCAPED BY string:用来指定转义字符,以便处理特殊字符或 解析特殊格式的数据。默认的转义字符是反斜杠(\)。
line_term
STARTING BY string:指定每一行的起始字符。TERMINATED BY string:指定每一行的结束字符,默认使用换行符。例如,... LINES TERMINATED BY '\n' ...表示一行将以换行符作为结束标志。
file_option
-
SINGLE [=] {TRUE | FALSE}:用于控制将数据导出到单个文件或多个文件。-
SINGLE [=] TRUE:默认值,表示只能导出到单个文件。 -
SINGLE [=] FALSE:表示可以导出到多个文件。提示当并行度大于 1 且
SINGLE = FALSE时,可以导出到多个文件,达到并行读并行写和提高导出速度的效果。
-
-
MAX_FILE_SIZE [=] {int | string}:用于控制导出时单个文件的大小,仅在SINGLE = FALSE时生效。 -
BUFFER_SIZE [=] {int | string}:用于控制导出时每个线程为每个分区专门申请的内存大小(不分区可视为单个分区),默认取值为 1 MB。信息BUFFER_SIZE用于导出性能调优,当机器内存充足且希望提高导出效率时,可设置一个较大的值(例如 4 MB),当机器内存不足时,可设置一个较小的值(例如 4 KB。设置为 0 时,表示单个线程中所有分区都使用一块公共内存)。- seekdb 支持
BUFFER_SIZE参数。
external_file_format_list
-
TYPE = 'CSV' 时,包含以下字段:
LINE_DELIMITER:指定 CSV 文件的行分隔符,默认为LINE_DELIMITER='\n'。FIELD_DELIMITER:可选项,指定 CSV 文件的列分隔符,默认为FIELD_DELIMITER='\t'。ESCAPE:指定 CSV 文件的转义符号,只能为 1 个字节,默认为ESCAPE ='\'。FIELD_OPTIONALLY_ENCLOSED_BY:可选项,指定 CSV 文件中包裹字段值的符号,默认为空。使用此选项表示只对部分类型的字段(如 CHAR, VARCHAR, TEXT, JSON 等)加包裹符。FIELD_ENCLOSED_BY:可选项,指定 CSV 文件中包裹字段值的符号,默认为空,表示不加包裹符。此选项会对所有类型的字段都应用包裹符的设置。ENCODING:指定文件的字符集编码格式,如果不指定,默认值为UTF8MB4。COMPRESSION:可选项,指定文件的压缩格式,支持 NONE、GZIP、DEFLATE、ZSTD 四种压缩格式。GZIP/DEFLATE:GZIP 压缩文件。ZSTD:ZSTD 压缩文件。NONE:表示文件没有压缩(默认值)。
FILE_EXTENSION:可选项,指定用户自定义的文件扩展名,仅多文件导出时使用,仅 CSV 格式支持指定。不指定该参数时,文件扩展名由格式类型决定。CSV 格式默认文件扩展名为.csv。
-
TYPE = 'PARQUET' 时,包含以下字段:
COMPRESSION:指定 PARQUET 文件的压缩格式,默认压缩后缀名为.parquet,支持UNCOMPRESSED(表示文件没有压缩)、SNAPPY、GZIP、BROTLI、ZSTD、LZ4、LZ4_HADOOP七种压缩格式。不指定时默认为UNCOMPRESSED。ROW_GROUP_SIZE:指定 PARQUET 文件的 ROW GROUP 大小,单位为字节。该选项可以写数字,或者写形如'64MB'的字符串,不指定时默认为256MB。推荐使用默认值。
-
TYPE = 'ORC' 时,包含以下字段:
COMPRESSION:指定 ORC 文件的压缩格式,默认压缩后缀名为.orc,支持UNCOMPRESSED(表示文件没有压缩)、SNAPPY、ZLIB、LZ4、ZSTD五种压缩格式。不指定时默认为UNCOMPRESSED。COMPRESSION_BLOCK_SIZE:指定数据在压缩时被分割成的块大小,单位为字节。该选项可以写数字,或者写形如'64KB'的字符串,不指定时默认为256KB。推荐使用默认值。STRIPE_SIZE:指定 ORC 文件的 Stripe 大小,单位为字节。该选项可以写数字,或者写形如'64MB'的字符串,不指定时默认为64MB。推荐使用默认值。ROW_INDEX_STRIDE:控制索引记录的频率的参数,定义了每隔多少行记录一次索引,不指定时默认为10000。推荐使用默认值。
示例
导出数据文件到本地
-
设置导出的文件路径。
要导出文件,需要先设置系统变量
secure_file_priv,配置导出文件可以访问的路径。提示由于安全原因,设置系统变量
secure_file_priv时,只能通过本地 Unix Socket 连接数据库执行修改该全局变量的 SQL 语句。更多信息,参见 secure_file_priv。-
登录到要连接 seekdb 的节点。
ssh admin@xxx.xxx.xxx.xxx -
执行以下命令,通过本地 Unix Socket 连接方式连接租户
mysql001。mysql -S /home/admin/oceanbase/run/sql.sock -uroot -p****** -
设置导出路径为
/home/admin/test_data。SET GLOBAL secure_file_priv = "/home/admin/test_data"; -
退出登录。
-
-
重新连接数据库后,使用
SELECT INTO OUTFILE语句导出数据。指定逗号作为两个字段值之间的标志;对字符串类型的值使用"字符包裹;使用换行符作为结束标志。-
串行写单个文件,指定文件名为
test_tbl1.csv。SELECT /*+parallel(2)*/ * FROM test_tbl1
INTO OUTFILE '/home/admin/test_data/test_tbl1.csv'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n';返回结果如下:
Query OK, 9 rows affected (0.087 sec) -
并行写多个文件,不指定文件名(即文件名使用默认前缀
data),并且每个文件的大小不超过 4MB。SELECT /*+parallel(2)*/ * FROM test_tbl1
INTO OUTFILE '/home/admin/test_data/'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
SINGLE = FALSE MAX_FILE_SIZE = '4MB';返回结果如下:
Query OK, 9 rows affected (0.093 sec) -
并行写多个文件,指定文件名的前缀为
dd2024,并且每个文件的大小不超过 4MB。SELECT /*+parallel(2)*/ * FROM test_tbl1
INTO OUTFILE '/home/admin/test_data/dd2024'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
SINGLE = FALSE MAX_FILE_SIZE = '4MB';返回结果如下:
Query OK, 9 rows affected
信息- 当多个导出任务同时导出到相同路径时,可能出现报错、只导出一部分数据等问题。可以通过合理设置导出路径规避。例如:
SELECT /*+parallel(2)*/ * FROM t1 INTO OUTFILE 'test/data' SINGLE = FALSE;和SELECT /*+parallel(2)*/ * FROM t2 INTO OUTFILE 'test/data' SINGLE = FALSE;同时执行时可能由于导出文件名相同而报错,建议将导出路径设置为test/data1和test/data2。 - 当
SINGLE = FALSE,且导出因为 file already exist 等原因失败后,可以清除导出目录下所有与导出目标具有相同前缀的文件,或者删除导出目录再重建,然后再次执行导出操作。例如:SELECT /*+parallel(2)*/ * FROM t1 INTO OUTFILE 'test/data' SINGLE = FALSE;失败后,可以删除test目录下所有data前缀的文件,或者直接删除test目录再重建,然后再次尝试执行导出操作。
-
-
登录机器,在 seekdb 节点的
/home/admin/test_data目录下查看导出的文件信息。
ls
返回结果如下:
data_0_0_0 data_0_1_0 dd2024_0_0_0 dd2024_0_1_0 test_tbl1.csv
其中,test_tbl1.csv 是串行写单个文件示例导出的文件名;data_0_0_0 和 data_0_1_0 是并行写多个文件,不指定文件名示例导出的文件名;dd2024_0_0_0 和 dd2024_0_1_0 是并行写多个文件,指定文件名的前缀为 dd2024 示例导出的文件名。
导出数据文件到 OSS
使用 SELECT INTO OUTFILE 语句从 test_tbl2 表中按分区导出数据到指定的 OSS 存储位置。分区依据是 col1 和 col2 列的组合,相同的行属于同一个分区,将导出到同一个目录中。
SELECT /*+parallel(3)*/ * FROM test_tbl2
INTO OUTFILE 'oss://$DATA_FOLDER_NAME/?host=$OSS_HOST&access_id=$OSS_ACCESS_ID&access_key=$OSS_ACCESS_KEY'
PARTITION BY CONCAT(col1,'/',col2)
SINGLE = FALSE BUFFER_SIZE = '2MB';
存储位置由 $DATA_FOLDER_NAME 变量指定,同时需要提供 OSS 的主机地址、访问 ID 和访问密钥。