繁体   English   中英

寻找最佳实践/最高效的大型SQL UPDATE / INSERT

[英]Looking for Best Practice / Most Efficient Large SQL UPDATE / INSERT

我正在寻找在SQL中实现大数据更新/插入的最佳方法。 我的特殊情况是使用MySQL 5.6,但从理论上讲,SQL版本并不那么重要。

我正在下载一个大型CSV文件,其中包含我需要转储到MySQL表中的数据。 我的应用程序解析CSV,并准备将其插入数据库。

我需要表是每次出现的数据(CSV)的精确副本,而不是每次都添加到末尾。 我正在寻找实现这一目标的最佳方法。

就我目前的SQL功能而言,我认为最好是每次都简单地截断该表并在数据通过时填充它,但是我现在不确定这是否比索引一个列并使用INSERT ... ON DUPLICATE KEY

我的问题如下:

  • 最好是截断然后将数据插入到空表中,还是最好查找数据差异并使用INSERT .. ON DUPLICATE KEY仅更新应用程序发现数据差异的行。

  • 无论采用哪种方法,最好是对每行数据格式化单个SQL UPDATE / INSERT查询并将其发送到服务器。 或者更好地格式化包含所有数据的超大型查询,或将较大的查询拆分为更易于管理的方式,以免服务器超时。

该表中大约有10万行。 当前,我在运行任何INSERT之前将表截断。 然后,我将行分为10个不同的集合,并对数据库运行10个大型INSERT查询。 我唯一关心的是,我对表锁定了解得不够多,并且不确定拆分这些表是否真正实现了重要意义。

我在这里提出这个问题的原因是因为监视器中的数据库使用率图表显示出峰值,并且我认为拥有稳定的数据流并尝试找出实现方法可能会更好。

数据库磁盘写入

我了解这只是磁盘写入,但是所有图形看起来或多或少都一样,有很多尖峰并且没有一致性。

处理大型csv文件时,应使用LOAD DATA LOCAL INFILE而不是插入/更新操作。 您没有提到插入之前要执行的解析操作,其中某些操作仅通过LOAD DATA LOCAL INFILE 在语句之前TRUNCATE表。

这是一个LOAD DATA LOCAL INFILE语句的示例,该语句在LOAD DATA LOCAL INFILE忽略第一行(标题)并替换价格字段的逗号值,例如:

LOAD DATA LOCAL INFILE 'file.csv' 
INTO TABLE table 
CHARACTER SET UTF8 
FIELDS TERMINATED BY '\t'
ENCLOSED BY '\"' 
IGNORE 1 LINES 
(col1,col2,col3,colN, @price) 
SET price = REPLACE(@price,',','.');

正如您所说的,您需要csv中的所有字段,只需在此处传递列名

(col1,col2,col3,colN, @price) 

按照与您在csv中相同的顺序。 这将比您可以编写的任何insert语句更快。

要启用LOAD DATA LOCAL INFILE ,您需要在建立与数据库的连接时设置连接标志(直接在连接选项中的选项内,之后将不起作用),例如使用php PDO:

$dbh = new PDO('mysql:host=' . env('DB_HOST') . ';dbname=' . $database, env('DB_USERNAME'), env('DB_PASSWORD'), 
               [PDO::MYSQL_ATTR_LOCAL_INFILE => 1]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM