ILo*_*low 10 c# sql linq algorithm ado.net
下面是我的应用程序数据库表,其中包含存储在表中的SQL查询:QueryStorage
Id Query ConnectionString Rdbms
1 select... Data Source Sql Server
2 select... Data Source Oracle
Run Code Online (Sandbox Code Playgroud)
上表中的SQL查询是通过Web服务更新的,我们不允许在查询之上更新,但我们可以在查询之外添加一些内容,如下所示:
存储在表中的查询: select id as LinkedColumn, Amount as CompareColumn from Source
来自我的c#app的调整查询:select Q.LinkedColumn, Q.CompareColumn from (stored sql query) as Q
我想比较下面的2个无序列表:
Id = 1(Sql server)从QueryStorage表记录执行的查询如下所示:
select Id as LinkedColumn,CompareColumn from Source
Run Code Online (Sandbox Code Playgroud)
清单1:
LinkedColumn CompareColumn
1 100
2 200
3 300
4 400
5 500
6 600
7 700
8 800
9 900
10 1000
Run Code Online (Sandbox Code Playgroud)
Id = 2(Oracle)从QueryStorage表记录执行的查询如下所示:
select Id as LinkedColumn,CompareColumn from Target
Run Code Online (Sandbox Code Playgroud)
清单2:
LinkedColumn CompareColumn
10 10
9 20
8 30
7 40
6 50
5 60
4 70
3 80
2 90
1 5
Run Code Online (Sandbox Code Playgroud)
我想加入LinkedColumn from source to target然后做比较,CompareColumn哪个应该给我以下输出:
SrcLinkedColumn SrcCompareColumn TgtLinkedColumn TgtCompareColumn
1 100 1 5
2 200 2 90
Run Code Online (Sandbox Code Playgroud)
逻辑:
var data = (from s in List1.AsEnumerable()
join t in List2.AsEnumerable() on s.Field<string>("LinkedColumn") equals t.Field<string>("LinkedColumn")
where s.Field<decimal>("CompareColumn") != t.Field<decimal>("CompareColumn")
select new
{
srcLinkedcol = s.Field<string>("LinkedColumn"),
srcCompareCol = s.Field<decimal>("CompareColumn"),
tgtLinkedCol = t.Field<string>("LinkedColumn"),
tgtCompareCol = t.Field<decimal>("CompareColumn")
}).ToList();
Run Code Online (Sandbox Code Playgroud)
从源到目标将有数百万条记录,我想out of memory exception通过将所有数据加载到内存中然后与上面的linq查询进行比较来解决我们现在面临的大问题.
我有两种解决方案,如下所示:
1)打开2个有序数据读取器.
优点:
- No memory exception
- Fast as there will be 1 to 1 comparision of LinkedColumn for List1 and
List2 records.
Run Code Online (Sandbox Code Playgroud)
缺点:
- Order by is require on LinkedColumns and as i have no control over
query as because it is dumped by webservice in QueryStorage table so
user is explicitly require to submit query with order by on
LinkedColumn.
- Wont work if order by on Linkedcolumn is not present.
- Order by query have performance overhead so because of this user may not include order by on LinkedColumn in query.
Run Code Online (Sandbox Code Playgroud)
2)通过调整查询和添加来比较块的大块记录OffSet and FetchRowNext.这就是我在思考算法的方式:
但我仍然觉得用第二种方法我可以得到内存异常问题,因为在源和目标数据不匹配的某些步骤中,我将它们存储在缓冲区(数据表或列表等)中以进行下一个块比较.
任何人都可以指导我应该是什么样的好算法或更好的方法来解决这个问题?
注意:我不想使用LinkedServer和SSIS.
您的第二个解决方案似乎是尝试重新创建外部合并排序.如果您的数据不适合内存,这是一种有效的方法,但当您的数据集适合内存时,它是过度的.
每行2,400万行(8字节)只有~200MB的内存.两个数据集是400MB.现代桌面硬件上没有任何内容.
将两个数据集加载到内存中.在简单的数组中.在内存中排序数组.通过扫描两个已排序的数组来查找差异.你不需要花哨的LINQ.
这是伪代码.我们有Array1和Array2.维护两个包含每个数组当前索引的变量:Idx1和Idx2.沿阵列移动索引以查找LinkedColumn匹配的位置.
Idx1 = 0; Idx2 = 0;
while (true)
{
// scan arrays until both indexes point to the same LinkedColumn
// here we assume that both arrays are sorted by LinkedColumn
// and that values in LinkedColumn are unique
while (Idx1 < Array1.Length && Idx2 < Array2.Length &&
Array1[Idx1].LinkedColumn < Array2[Idx2].LinkedColumn)
{
// move along Array1
Idx1++;
}
while (Idx1 < Array1.Length && Idx2 < Array2.Length &&
Array1[Idx1].LinkedColumn > Array2[Idx2].LinkedColumn)
{
// move along Array2
Idx2++;
}
// at this point both indexes point to the same LinkedColumn
// or one or both of the arrays are over
if (Idx1 >= Array1.Length || Idx2 >= Array2.Length)
{
break;
}
// compare the values
if (Array1[Idx1].CompareColumn != Array2[Idx2].CompareColumn)
{
// TODO: output/save/print the difference
}
Idx1++; Idx2++;
}
Run Code Online (Sandbox Code Playgroud)
您可以将两个数据集转储到您选择的数据库中的两个表中,T1并在两个表中T2创建唯一索引LinkedColumn并运行此查询:
SELECT
T1.LinkedColumn AS SrcLinkedColumn
,T1.CompareColumn AS SrcCompareColumn
,T2.LinkedColumn AS DstLinkedColumn
,T2.CompareColumn AS DstCompareColumn
FROM
T1 INNER JOIN T2 ON T1.LinkedColumn = T2.LinkedColumn
WHERE
T1.CompareColumn <> T2.CompareColumn
ORDER BY
T1.LinkedColumn
;
Run Code Online (Sandbox Code Playgroud)
上面的伪代码执行与DBMS服务器为此查询执行的相同的合并连接.
小智 0
抱歉,我只能给你一个想法:
限制条件:
想法:
奖金 :
您可能会发现一些类似(或高级)的解决方案,例如:
抱歉,但(至少对我来说)这个箱子太大了,仅使用一台机器就无法处理
我希望至少这能给你一个想法