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';