Ускорение за счет многопоточности
На клиент из SQL сервера берутся данные и выполняется с ними некая математика, таким образом, что для каждой строки запроса (их очень много ~20-30млн) выполняется на сервер запрос, т.е. каждая последующая запись является входными данными для запроса по предыдущим записям.
Процессорное время в начале выполнения алгоритма распределяется 50/50 между сервером и приложением, а к концу работы 90-95 сервер/5-10 клиент.
Хочу оптимизировать алгоритм за счет выделения стека запросов в отдельный поток, управлять которым будет основной. Поток стека запросов будет "наполнять" массив входных данных (FIFO), таким образом пока клиент обрабатывает свою математику, сервер делает запросы.
Но, т.к. в конечном итоге нагрузка на сервер намного больше будет, то потребуется синхронизация (пока в массиве входных данных не будет данных математика на клиенте должна тормознуться)
Вопрос:
1. Не будет ли при таком подходе лишней нагрузки за счет синхронизации, что в итоге отрицательно скажется на производительности.
2. Правильно ли все вышеизложенное, или м.б. есть какие то другие пути?
На клиент из SQL сервера берутся данные и выполняется с ними некая математика, таким образом, что для каждой строки запроса (их очень много ~20-30млн) выполняется на сервер запрос, т.е. каждая последующая запись является входными данными для запроса по предыдущим записям.
А разве нельзя это сделать вложеными запросами? То-есть, грубо говоря запрос в запросе.
Думал об этом (сделать пробег по выборке на сервере), но там довольно приличная математика и вне концепции ООП придется такой огород нагородить, и тогда от многопоточности вообще можно отказаться.
для примера:
есть таблица:
1 | 100 | 110 | 150
2 | 108 | 113 | 120
3 | 160 | 170 | 350
4 | 188 | 550 | 188
которые формируются особым образом
из значений Param1 | Param2 | Param3
для 3-й строки)
На первый взгляд, синхронизация не будет давать большого оверхеда, да и формирование конвеера запросов тоже удачная мысль...
...Проблема в том, что запрос к базе в данном случае уже сам по себе большущий оверхед.
На мой взгляд, нужно делать кэш таблицы данных на клиенте и ворочать запросами поверх кэша и постепенно подкачивать таблицу с сервера. Но для этого придется реализовывать паттерн "запроса" (QueryObject), если все происходит в .net можно использовать LINQ.
все дело в том что процессорное время по большому счету хавает сервер, а клиент и так ждет, пока сервер обработает + если к этому на клиенте добавить синхронизацию, то мне кажется получится дополнительная совершенно не нужная нагрузка на него, которая не приведет к ускорению.
На мой взгляд, нужно делать кэш таблицы данных на клиенте и ворочать запросами поверх кэша и постепенно подкачивать таблицу с сервера. Но для этого придется реализовывать паттерн "запроса" (QueryObject), если все происходит в .net можно использовать LINQ.
собственно и так кэш таблицы помещается на клиента, а потом по этому кэшу уже бегаем и строим запросы на сервер... или я не правильно понял, и надо делать запрос не на сервер а в кэш?
Именно. Если хотя бы часть запросов можно выполнить поверх кэша таблицы на клиенте, то это может повысить производительность в целом: нагрузка простаивающего клиента, снижение нагрузки на сервер, снижение нагрузки на сеть.
следуя подобной логике, можно подключить к одному клиенту более одного сервера (собственно в количестве никто не ограничивает) и делать поочередно на каждом из серверов свои части запросов :)
ЗЫ: синхронизация не потребуется, т.к. данные не изменяются