Ниже приведена таблица моей базы данных приложений, содержащая SQL-запросы, хранящиеся в таблице: QueryStorage
Id Query ConnectionString Rdbms
1 select... Data Source Sql Server
2 select... Data Source Oracle
SQL-запросы в приведенной выше таблице обновляются через веб-службу, и нам не разрешено обновлять их выше, хотя мы можем добавить что-то поверх запроса примерно так:
Запрос хранится в таблице: select id as LinkedColumn, Amount as CompareColumn from Source
Тонкий запрос из моего приложения С#: select Q.LinkedColumn, Q.CompareColumn from (stored sql query) as Q
Я пытаюсь сравнить 2 неупорядоченных списка, как показано ниже:
Выполняется запрос для Id = 1(Sql server)
из записей таблицы QueryStorage:
select Id as LinkedColumn,CompareColumn from Source
Список 1:
LinkedColumn CompareColumn
1 100
2 200
3 300
4 400
5 500
6 600
7 700
8 800
9 900
10 1000
Запрос, выполненный для Id = 2(Oracle)
из QueryStorage, выглядит следующим образом:
select Id as LinkedColumn,CompareColumn from Target
Список 2:
LinkedColumn CompareColumn
10 10
9 20
8 30
7 40
6 50
5 60
4 70
3 80
2 90
1 5
Я хочу присоединиться к LinkedColumn from source to target
, а затем выполнить сравнение на CompareColumn
, которое должно дать мне следующий вывод:
SrcLinkedColumn SrcCompareColumn TgtLinkedColumn TgtCompareColumn
1 100 1 5
2 200 2 90
Логика:
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();
Будет миллионы записей из источника в цель, которые я хочу сравнить с такой большой проблемой, из 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.
Минусы:
- 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.
2) Сравните фрагмент с помощью записей chunk, изменив запрос и добавив OffSet and FetchRowNext
. Вот как я думаю об алгоритме:
Но я все еще чувствую, что со вторым подходом я могу получить проблему с исключением памяти, потому что на некоторых шагах, где данные из источника и цели не совпадают, я буду хранить их внутри буфера (datatable или list и т.д.) для следующего сравнения chunk.
Может кто-нибудь, пожалуйста, назовите меня, какой должен быть хороший алгоритм для этого или любой лучший способ решить эту проблему?
Примечание. Я не хочу использовать LinkedServer и SSIS.