目前,我正在寻找一种解决方案来加速我的代码。我有一个具有不同几何组件(点、多边形)的数据库。每个结构都由多个属性给出,称为 Con_Number(默认值:0)、LayerName、单个索引 (ObjectIndex)。因此每个实例的 Con_Number 应该是相同的值...
- 在同一层上重叠的结构。
- 在相邻层上重叠的结构。
我使用 STIntersects 命令获取重叠实例。
sqlString :=
'declare @g geometry select @g = Geom from obj where ObjectIndex = :index
select ObjectIndex, Con_Number from obj WITH(index(idx_Spatial)) where Geom.STIntersects(@g) = 1 and
ObjectLayerName in (' + QuotedStrList(neighbourLayers) + ')';
我试图在遍历某一层的所有元素的并行循环中执行此算法。之后,我在单独的连接/查询上为每个实例运行 SqlCommand。结果将根据不同 con_number 的数量进行不同的处理。最后但同样重要的是,重叠结构的 Con_number 将被更新。
- 步骤:找到所有重叠的元素!
步骤:更新重叠元素的 Con_Number!
Parallel.ForEach<Integer>(indexList) .NumTasks(ThreadCount).Execute( procedure(const item: Integer) var Con_Number: Integer; Con_List: TIntegerList; begin //Create TADOConnection and TADOQueries // 1.STEP: get signals of all overlapping elements ADOQueryOverlap.SQL.Text := sqlString; ADOQueryOverlap.ParamCheck := True; ADOQueryOverlap.Parameters.ParamByName('index').DataType := ftInteger; ADOQueryOverlap.Parameters.ParamByName('index').Value := item; ADOQueryOverlap.Open; ADOQueryOverlap.First; while not ADOQueryOverlap.Eof do begin indexThreadList.add(ADOQueryOverlap.FieldByName('ObjectIndex') .AsInteger); Con_Number:= ADOQueryOverlap.FieldByName('Con_Number').AsInteger; if (Con_List.IndexOf(Con_Number) < 0) and (Con_Number > 0) then begin Con_List.add(Con_Number); end; ADOQueryOverlap.next; end; //2. STEP UPDATE CON_NUMBER if indexThreadList.Count > 0 then begin // elements have no Con_Number -> Assign new Con_Number to overlapping elements if signalList.Count = 0 then begin InterlockedIncrement(FId); ADOQueryWriteBack.SQL.Text := 'update obj set Con_Number = ' + FId.ToString + ' where ObjectIndex in (' + indexThreadList.AsString + ')'; ADOQueryWriteBack.ExecSQL; end; // one Con_Number exist -> write that number to all other objects if signalList.Count = 1 then begin ADOQueryWriteBack.SQL.Text := 'update obj set Con_Number = ' + Con_List.Items[0].ToString + ' where ObjectIndex in (' + indexThreadList.AsString + ')'; ADOQueryWriteBack.ExecSQL; end; // more than 1 Con_Number exists -> Take one Con_Number and overwrite other Con_Numbers if signalList.Count > 1 then begin ADOQueryWriteBack.SQL.Text := 'update obj set Con_Number = ' + Con_List.Items[0].ToString + ' where ObjectIndex in (' + indexThreadList.AsString + ') or Con_Number in (' + Con_List.GetListAsStringFromIndex(1) + ')'; ADOQueryWriteBack.ExecSQL; end; end;
目前,我试图获得更好的表现。此外,线程在一段时间(几个小时)后崩溃。你认为多线程适合我的应用吗?你有其他改进的想法吗?