Greetings, I've the following table:
CREATE TABLE STOCK_RECORDS ( ID INTEGER NOT NULL, LOCATION SMALLINT, INSERTUSER SMALLINT DEFAULT 0, <-- FOREIGN KEY CONSTRAINT INSERTDATE TIMESTAMP, EDITUSER SMALLINT DEFAULT 0, <-- FOREIGN KEY CONSTRAINT EDITDATE TIMESTAMP, PRODUCTID INTEGER, <-- FOREIGN KEY CONSTRAINT RECORD_DATE TIMESTAMP, RECORD_TYPE SMALLINT DEFAULT 0, STORAGE_AREA_ID_SOURCE INTEGER, <-- FOREIGN KEY CONSTRAINT STORAGE_AREA_ID_TARGET INTEGER, <-- FOREIGN KEY CONSTRAINT INVENTORYPOSID INTEGER, <-- FOREIGN KEY CONSTRAINT PURCHASEORDERPOSID INTEGER, <-- FOREIGN KEY CONSTRAINT DELIVERYPOSID INTEGER, <-- FOREIGN KEY CONSTRAINT INVOICEPOSID INTEGER, <-- FOREIGN KEY CONSTRAINT INSTANCE_TYPE SMALLINT, INSTANCE_ID INTEGER, AMOUNT DOUBLE PRECISION, RESULTING_AMOUNT DOUBLE PRECISION, NOTES VARCHAR( 255), STOCK_RELEVANT BOOLEAN ); ALTER TABLE STOCK_RECORDS ADD CONSTRAINT PK_STOCK_RECORDS PRIMARY KEY(ID); CREATE GENERATOR STOCK_RECORDS_PRIMARYKEY; CREATE ASC INDEX STOCK_RECORDS_LOCATION ON STOCK_RECORDS (LOCATION); CREATE ASC INDEX STOCK_RECORDS_RECORD_DATE ON STOCK_RECORDS (RECORD_DATE); CREATE ASC INDEX STOCK_RECORDS_RECORD_TYPE ON STOCK_RECORDS (RECORD_TYPE); CREATE ASC INDEX STOCK_RECORDS_INSTANCE_TYPE ON STOCK_RECORDS (INSTANCE_TYPE); The domain "BOOLEAN" is defined like this: CREATE DOMAIN BOOLEAN AS SMALLINT DEFAULT 0 CHECK (VALUE IN (-1, 0)) NOT NULL; In an update procedure I'm doing the following by using IBOjects: .... IBOQueryStockRecords.ReadOnly := False; IBOQueryStockRecords.RequestLive := True; IBOQueryStockRecords.Close; IBOQueryStockRecords.SQL.Clear; IBOQueryStockRecords.SQL.Add('select ID, EDITDATE, PRODUCTID, DELIVERYPOSID as POSID, abs(AMOUNT) as AMOUNT, RESULTING_AMOUNT from MOV_STOCK_RECORDS where (INSTANCE_TYPE = 2)'); IBOQueryStockRecords.Open; if not (IBOQueryStockRecords.Bof and IBOQueryStockRecords.Eof) then begin with IBCursorResultingStock do begin Close; SQL.Clear; SQL.Add('select sum(AMOUNT) as GESAMTBESTAND from MOV_STOCK_RECORDS where (ID > 0) and (PRODUCTID = :PRODUCTID) and (STORAGE_AREA_ID_SOURCE = :STORAGE_AREA_ID_SOURCE) and (STOCK_RELEVANT = -1)'); SQL.Add('and ((DELIVERYPOSID <> :DELIVERYPOSID) or DELIVERYPOSID is null)'); SQL.Add('and (EDITDATE <= :EDITDATE)'); Prepare; end; IBOQueryStockRecords.First; while not IBOQueryStockRecords.Eof do begin with IBCursorResultingStock do begin Close; ParamByName('PRODUCTID').AsInteger := IBOQueryStockRecords.FieldByName('PRODUCTID').AsInteger; ParamByName('STORAGE_AREA_ID_SOURCE').AsInteger := 1; ParamByName('DELIVERYPOSID').AsInteger := IBOQueryStockRecords.FieldByName('POSID').AsInteger; ParamByName('EDITDATE').AsDateTime := IBOQueryStockRecords.FieldByName('EDITDATE').AsDateTime; Open; First; if not (Bof and Eof) then begin ResStockAmount := Fields[0].AsFloat; end; end; if IBOQueryStockRecords.FieldByName('RESULTING_AMOUNT').AsFloat <> ResStockAmount then begin IBOQueryStockRecords.Edit; IBOQueryStockRecords.FieldByName('RESULTING_AMOUNT').AsFloat := ResStockAmount; IBOQueryStockRecords.Post; end; IBOQueryStockRecords.Next; end; end; .... For ca. 100k records as the result of the select statement of IBOQueryStockRecords updating the values takes very long. I also tried to use an IB_Script rather than editing the records directly, but this didn't change much. Apparently selecting the sum of AMOUNT with IBCursorResultingStock is what adds in execution time of the procedure the most. Do you guys see any potential for improvement by adding some indexes or something? There was an other procedure that took long, and I was able to drasticaly improve it by adding one multi-segment index, but all my attempts to do the same in the case above didn't have much impact so far. Best regards,Patrick