我正在尝试使用 linq2db 进行“数据库端”批量复制(即 SELECT INTO/INSERT INTO)。但是,我的代码试图将数据集传输到网络上,鉴于所讨论的数据库的大小,这是不可能的。
我的代码如下:
using (var db = new MyDb()) {
var list = db.Sourcetable.
Where(s => s.Year > 2012).
GroupBy(s => new { s.Column1,s.Column2 }).
Select(g => new DestinationTable {
Property1 = 'Constant Value',Property2 = g.First().Column1,Property3 = g.First().Column2,Property4 = g.Count(s => s.Column3 == 'Y')
});
db.Execute("TRUNCATE TABLE DESTINATION_TABLE");
db.BulkCopy(new BulkCopyOptions {
BulkCopyType = BulkCopyType.MultipleRows
},list);
}
生成的 SQL 如下所示:
BeforeExecute
-- DBNAME SqlServer.2017
TRUNCATE TABLE DESTINATION_TABLE
DataConnection
Query Execution Time (AfterExecute): 00:00:00.0361209. Records Affected: -1.
DataConnection
BeforeExecute
-- DBNAME SqlServer.2017
DeclARE @take Int -- Int32
SET @take = 1
DeclARE @take_1 Int -- Int32
SET @take_1 = 1
DeclARE @take_2 Int -- Int32
...
SELECT
(
SELECT TOP (@take)
[p].[YEAR]
FROM
[dbo].[SOURCE_TABLE] [p]
WHERE
(([p_16].[YEAR] = [p].[YEAR] OR [p_16].[YEAR] IS NULL AND [p].[YEAR] IS NULL) AND ...
...)
FROM SOURCE_TABLE p_16
WHERE p_16.YEAR > 2012
GROUP BY
...
DataConnection
这就是由于批量复制失败并超时而记录的全部内容,即 SqlException“执行超时已过期”。
请注意,将此查询作为 INSERT INTO 语句直接在数据库中运行所需的时间不到 1 秒。
PS:任何人都对基于良好代码的 ETL 工具进行大型 DB (+ 1 TB) ETL 有任何建议。鉴于数据库大小,我需要在数据库中运行的东西,而不是通过网络传输数据。我试过 pyspark、python bonobo、c# etlbox,它们都移动了太多的数据。我认为 linq2db 有潜力,即基本上就像 C# 到 SQL 的转译器一样,但它也在尝试移动数据。