Hello.
Could you tell me why there is a difference in performance between 3.0.10 and 2.5.7?
I'll give below DDL of table, but first the update:
update KOSZT
set KOSZT = KOSZT + WARTOSC - WARTOSC
where ID_ZLECENIE = 10032 and
   ID_OPERACJA = 10063 and
   ID_MELDUNEK is null and
   PLANOWANY = 0;
Firebird 3.0.10: PLAN (KOSZT INDEX (FK_KOSZT_MELDUNEK)). Execution: 62 ms.
Select Expression
  -> Filter
    -> Table "KOSZT" Access By ID
      -> Bitmap
        -> Index "FK_KOSZT_MELDUNEK" Range Scan (full match)
Firebird 2.5.7: PLAN (KOSZT INDEX (FK_KOSZT_MELDUNEK, FK_KOSZT_OPERACJA)). Execution: 16 ms!!
As you can see, Firebird 3.0.10 uses only one foreign key, Firebird 2.5.7 uses 2. This is serious issue. In our system one activity can take several or more such updates. The more updates, the more performance decrease.
DDL:
/******************************************************************************/
/**** Â Â Â Â Â Â Â Generated by IBExpert 23.08.2022 11:50:10 Â Â Â Â Â Â Â ****/
/******************************************************************************/
/******************************************************************************/
/****   Following SET SQL DIALECT is just for the Database Comparer    ****/
/******************************************************************************/
SET SQL DIALECT 3;
/******************************************************************************/
/****                 Tables                 ****/
/******************************************************************************/
CREATE TABLE KOSZT (
  ID_KOSZT   T_ID NOT NULL /* T_ID = INTEGER */,
  ID_ZLECENIE  T_ID NOT NULL /* T_ID = INTEGER */,
  ID_OPERACJA  T_ID NOT NULL /* T_ID = INTEGER */,
  ID_MELDUNEK  T_ID /* T_ID = INTEGER */,
  PLANOWANY   T_BOOLEANT DEFAULT 1 NOT NULL /* T_BOOLEANT = SMALLINT DEFAULT 1 */,
  KM      T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KM_NARZUT   T_PROCENT DEFAULT 0 NOT NULL /* T_PROCENT = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KM_RAZEM   T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KMD      T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KMD_NARZUT  T_PROCENT DEFAULT 0 NOT NULL /* T_PROCENT = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KMD_RAZEM   T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KO      T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KO_NARZUT   T_PROCENT DEFAULT 0 NOT NULL /* T_PROCENT = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KO_RAZEM   T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KK      T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KK_NARZUT   T_PROCENT DEFAULT 0 NOT NULL /* T_PROCENT = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KK_RAZEM   T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KR      T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KR_NARZUT   T_PROCENT DEFAULT 0 NOT NULL /* T_PROCENT = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KR_RAZEM   T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KG      T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KG_NARZUT   T_PROCENT DEFAULT 0 NOT NULL /* T_PROCENT = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KG_RAZEM   T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KN      T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KN_NARZUT   T_PROCENT DEFAULT 0 NOT NULL /* T_PROCENT = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KN_RAZEM   T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KD      T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KD_NARZUT   T_PROCENT DEFAULT 0 NOT NULL /* T_PROCENT = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KD_RAZEM   T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KOSZT     T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  NARZUT    T_PROCENT DEFAULT 0 NOT NULL /* T_PROCENT = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  WARTOSC    T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KP      T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KP_NARZUT   T_PROCENT DEFAULT 0 NOT NULL /* T_PROCENT = NUMERIC(18,4) DEFAULT 0 NOT NULL */,
  KP_RAZEM   T_KWOTA DEFAULT 0 NOT NULL /* T_KWOTA = NUMERIC(18,4) DEFAULT 0 NOT NULL */
);
/******************************************************************************/
/****               Primary keys               ****/
/******************************************************************************/
ALTER TABLE KOSZT ADD CONSTRAINT PK_KOSZT PRIMARY KEY (ID_KOSZT);
/******************************************************************************/
/****               Foreign keys               ****/
/******************************************************************************/
ALTER TABLE KOSZT ADD CONSTRAINT FK_KOSZT_MELDUNEK FOREIGN KEY (ID_MELDUNEK) REFERENCES MELDUNEK (ID_MELDUNEK) ON DELETE CASCADE;
ALTER TABLE KOSZT ADD CONSTRAINT FK_KOSZT_OPERACJA FOREIGN KEY (ID_OPERACJA) REFERENCES OPERACJA (ID_OPERACJA) ON DELETE CASCADE;
ALTER TABLE KOSZT ADD CONSTRAINT FK_KOSZT_ZLECENIE FOREIGN KEY (ID_ZLECENIE) REFERENCES ZLECENIE (ID_ZLECENIE) ON DELETE CASCADE;
/******************************************************************************/
/****                Indices                 ****/
/******************************************************************************/
CREATE INDEX MK_PLANOWANY ON KOSZT (PLANOWANY);
/******************************************************************************/
/****                Triggers                ****/
/******************************************************************************/
SET TERM ^ ;
/******************************************************************************/
/****             Triggers for tables              ****/
/******************************************************************************/
/* Trigger: KOSZT_AD */
CREATE OR ALTER TRIGGER KOSZT_AD FOR KOSZT
ACTIVE AFTER DELETE POSITION 0
AS
begin
 IF ((old.id_meldunek is not null) and (old.planowany = 0)) THEN
  update koszt set
   km = km - old.km_razem,
   kp = kp - old.kp_razem,
   kmd = kmd - old.kmd_razem,
   ko = ko - old.ko_razem,
   kk = kk - old.kk_razem,
   kr = kr - old.kr_razem,
   kg = kg - old.kg_razem,
   kn = kn - old.kn_razem,
   kd = kd - old.kd_razem,
   koszt = koszt - old.wartosc
  where id_zlecenie = old.id_zlecenie
   and id_operacja = old.id_operacja
   and id_meldunek is null
   and planowany = 0;
end
^
/* Trigger: KOSZT_AU */
CREATE OR ALTER TRIGGER KOSZT_AU FOR KOSZT
ACTIVE AFTER UPDATE POSITION 0
AS
begin
 IF ((new.id_meldunek is not null) and (new.planowany = 0)) THEN
  update koszt set
   km = km + new.km_razem - old.km_razem,
   kp = kp + new.kp_razem - old.kp_razem,
   kmd = kmd + new.kmd_razem - old.kmd_razem,
   ko = ko + new.ko_razem - old.ko_razem,
   kk = kk + new.kk_razem - old.kk_razem,
   kr = kr + new.kr_razem - old.kr_razem,
   kg = kg + new.kg_razem - old.kg_razem,
   kn = kn + new.kn_razem - old.kn_razem,
   kd = kd + new.kd_razem - old.kd_razem,
   koszt = koszt + new.wartosc - old.wartosc
  where id_zlecenie = new.id_zlecenie
   and id_operacja = new.id_operacja
   and id_meldunek is null
   and planowany = 0;
end
^
/* Trigger: KOSZT_BU0 */
CREATE OR ALTER TRIGGER KOSZT_BU0 FOR KOSZT
ACTIVE BEFORE UPDATE POSITION 0
AS
DECLARE VARIABLE wNIEWLICZAJDOKOSZT integer;
begin
 new.km_razem = new.KM + cast((new.KM * new.KM_NARZUT / 100) as numeric(18,4));
 new.kp_razem = new.Kp + cast((new.Kp * new.Kp_NARZUT / 100) as numeric(18,4));
 new.kmd_razem = new.KMd + cast((new.KMd * new.KMd_NARZUT / 100) as numeric(18,4));
 new.ko_razem = new.Ko + cast((new.Ko * new.Ko_NARZUT / 100) as numeric(18,4));
 new.kk_razem = new.Kk + cast((new.Kk * new.Kk_NARZUT / 100) as numeric(18,4));
 new.kr_razem = new.Kr + cast((new.Kr * new.Kr_NARZUT / 100) as numeric(18,4));
 new.kg_razem = new.Kg + cast((new.Kg * new.Kg_NARZUT / 100) as numeric(18,4));
 new.kn_razem = new.Kn + cast((new.Kn * new.Kn_NARZUT / 100) as numeric(18,4));
 new.kd_razem = new.Kd + cast((new.Kd * new.Kd_NARZUT / 100) as numeric(18,4));
 IF ((new.planowany = 1) or (new.id_meldunek is not null)) THEN begin
  wNIEWLICZAJDOKOSZT = 0;
  select NIEWLICZAJDOKOSZT
  from operacja
  where id_Operacja = new.id_operacja
  into :wNIEWLICZAJDOKOSZT;
  new.koszt = new.kd_razem;
  IF (bin_AND(:wNIEWLICZAJDOKOSZT, 1) = 0) THEN
   new.koszt = new.koszt + new.km_razem;
  IF (bin_AND(:wNIEWLICZAJDOKOSZT, 2) = 0) THEN
   new.koszt = new.koszt + new.kp_razem;
  IF (bin_AND(:wNIEWLICZAJDOKOSZT, 4) = 0) THEN
   new.koszt = new.koszt + new.kmd_razem;
  IF (bin_AND(:wNIEWLICZAJDOKOSZT, 8) = 0) THEN
   new.koszt = new.koszt + new.ko_razem;
  IF (bin_AND(:wNIEWLICZAJDOKOSZT, 16) = 0) THEN
   new.koszt = new.koszt + new.kk_razem;
  IF (bin_AND(:wNIEWLICZAJDOKOSZT, 32) = 0) THEN
   new.koszt = new.koszt + new.kr_razem;
  IF (bin_AND(:wNIEWLICZAJDOKOSZT, 64) = 0) THEN
   new.koszt = new.koszt + new.kg_razem;
  IF (bin_AND(:wNIEWLICZAJDOKOSZT, 128) = 0) THEN
   new.koszt = new.koszt + new.kn_razem;
 end
 IF (new.koszt < 0) THEN
  new.koszt = 0;
 new.wartosc = new.koszt + cast((new.koszt * new.narzut / 100) as numeric(18,4));
end
^
SET TERM ; ^
/******************************************************************************/
/****             Fields descriptions              ****/
/******************************************************************************/
COMMENT ON COLUMN KOSZT.KM_RAZEM IS
'Trigger';
COMMENT ON COLUMN KOSZT.KMD_RAZEM IS
'Trigger';
COMMENT ON COLUMN KOSZT.KO_RAZEM IS
'Trigger';
COMMENT ON COLUMN KOSZT.KK_RAZEM IS
'Trigger';
COMMENT ON COLUMN KOSZT.KR_RAZEM IS
'Trigger';
COMMENT ON COLUMN KOSZT.KG_RAZEM IS
'Trigger';
COMMENT ON COLUMN KOSZT.KN_RAZEM IS
'Trigger';
COMMENT ON COLUMN KOSZT.KD_RAZEM IS
'Trigger';
COMMENT ON COLUMN KOSZT.KOSZT IS
'Trigger';
COMMENT ON COLUMN KOSZT.WARTOSC IS
'Trigger';
COMMENT ON COLUMN KOSZT.KP_RAZEM IS
'Trigger';