Нельзя строить команды SQL путем объединения значений в нем, таких как [Identifier]='" + Identifier + "'
. Это вектор атаки SQL-инъекций, вы никогда не должны писать такой код. Используйте параметры: [Identifier] = @identifier
и добавьте значение параметра в команду. Прежде чем продолжить, сделайте себе одолжение и прочитайте Как код доступа к данным влияет на производительность базы данных .
Добавление потоков и тошноты не заставляет код работать быстрее, он будет работать медленнее . Если вы хотите добиться большей пропускной способности, вы должны использовать асинхронные команды базы данных. Убедитесь, что вы украсили строку подключения с помощью AsyncronouwProcessing = true
, затем используйте BeginExecuteReader
. Отрегулируйте количество невыполненных запросов.
Использование DataAdapater и DataTable - верный способ снизить производительность. Используйте raw SqlDataReader . Я снова отсылаю вас к статье Боба Бошамина, на которую ссылались ранее.
Не выполняйте обработку на клиенте, SQL Server намного лучше .
Не выполняйте построчно-медленную обработку строк, используйте ориентированную на множество логику. Рекурсивные CTE могут использоваться для иерархической обработки, см. Использование общих табличных выражений .
Есть еще много проблем с вашим кодом (например, наличие цикла событий, четкое указание на то, что этот код не принадлежит потоку пользовательского интерфейса, частые вызовы ToString()
, ясно указывающие на отсутствие понимания системы типов явные вызовы Dispose
вместо того, чтобы полагаться на блоки using(...)
, слепое повторное открытие соединений и т. д. и т. д. и т. п.
В первую очередь вы должны сосредоточиться на решении проблемы, выражая ее в виде единого оператора UPDATE на основе CTE. Без полного определения схемы данных и требований можно только догадываться, что вы пытаетесь сделать, но это будет примерно так:
with cte as (
select Node, NodeID, ParentId, Depth, 0 as ComputedDepth
from tblTree
where [Identifier]= @Identifier
union all
select c.Node, c.NodeID, c.ParentId, c.Depth, p.ComputedDepth+1
from tblTree c
join cte p on c.ParentId = p.NodeId)
update cte
set Depth = ComputedDepth;
Вот фактический пример:
create table tblTree (
[NodeID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[Identifier] [varchar](10) NULL,
[ParentID] [int] NULL,
[Depth] [tinyint] NULL);
GO
insert into tblTree (Identifier, ParentID)
values ('Foo', NULL)
, (NULL, 1)
, (NULL, 1)
, (NULL, 2)
, (NULL, 4)
, ('Bar', NULL);
go
declare @identifier VARCHAR(10) = 'Foo';
with cte as (
select NodeID, 0 as Depth
from tblTree
where Identifier = @identifier
union all
select c.NodeID, p.Depth+1
from tblTree c
join cte p on c.ParentID = p.NodeID)
update t
set t.Depth = c.Depth
from tblTree t
join cte c on t.NodeID = c.NodeID;
go
select * from tblTree;