使用 COPY 语句进行批量加载
一次将大量数据加载(批量加载)到 Vertica 的最快方法之一是使用 COPY 语句。此语句可将存储在 Vertica 主机上的文件中的数据(或数据流中的数据)加载到数据库中的表。可以向 COPY 语句传递定义了以下设置的参数:文件中的数据的格式、加载数据时对数据的转换方式、对错误的处理方式以及加载数据的方式。有关详细信息,请参阅 COPY 文档。
重要
在 Vertica ≤ 9.2 版本中创建的数据库中,COPY 支持 DIRECT 选项,该选项指定将数据直接加载到
ROS 而不是 WOS。将大型 (>100MB) 文件加载到数据库时使用此选项;否则,负载可能会填满 WOS。发生这种情况时, Tuple Mover 必须对 WOS 数据执行 移出 操作。直接加载到 ROS 更高效,并且可避免强制执行 moveout。
在 Vertica 9.3 中创建的数据库中,Vertica 忽略加载选项和提示,并始终使用 DIRECT 加载方法。≥ 10.0 版本创建的数据库不再支持 WOS 和移出操作;所有数据总是直接加载到 ROS 中。
只有 超级用户可以使用 COPY 语句复制存储在主机上的文件,因此您必须使用超级用户帐户连接到数据库。如果要以非超级用户身份批量加载数据,您可以使用 COPY 从主机上的流(例如 STDIN)而非文件加载数据,或者也可以从客户端以流式传输数据(请参阅通过 JDBC 进行流式数据传输)。您还可以执行使用预定义的语句的批量插入(此为标准方式),这种方式在后台使用 COPY 语句来加载数据。
注意
使用 COPY 参数ON ANY NODE
时,请确认所有节点上的源文件均相同。使用不同的文件会导致生成的结果不一致。
以下示例演示了通过 JDBC 使用 COPY 语句将名为 customers.txt
的文件加载到新的数据库表。该文件必须存储在应用程序连接到的数据库主机(在此示例中是名为 VerticaHost 的主机)上。
import java.sql.*;
import java.util.Properties;
import com.vertica.jdbc.*;
public class COPYFromFile {
public static void main(String[] args) {
Properties myProp = new Properties();
myProp.put("user", "ExampleAdmin"); // Must be superuser
myProp.put("password", "password123");
Connection conn;
try {
conn = DriverManager.getConnection(
"jdbc:vertica://VerticaHost:5433/ExampleDB",myProp);
// Disable AutoCommit
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
// Create a table to hold data.
stmt.execute("DROP TABLE IF EXISTS customers;");
stmt.execute("CREATE TABLE IF NOT EXISTS customers (Last_Name char(50) "
+ "NOT NULL, First_Name char(50),Email char(50), "
+ "Phone_Number char(15))");
// Use the COPY command to load data. Use ENFORCELENGTH to reject
// strings too wide for their columns.
boolean result = stmt.execute("COPY customers FROM "
+ " '/data/customers.txt' ENFORCELENGTH");
// Determine if execution returned a count value, or a full result
// set.
if (result) {
System.out.println("Got result set");
} else {
// Count will usually return the count of rows inserted.
System.out.println("Got count");
int rowCount = stmt.getUpdateCount();
System.out.println("Number of accepted rows = " + rowCount);
}
// Commit the data load
conn.commit();
} catch (SQLException e) {
System.out.print("Error: ");
System.out.println(e.toString());
}
}
}
运行此示例后,将在系统控制台上输出以下内容(假设 customers.txt
文件两百万个有效的行):
Number of accepted rows = 2000000