triggersquery-optimizationhana

Performance implications of INSERT INTO...SELECT :NEW.FIELD FROM DUMMY


Let's say we have a table BASE in a HANA:

CREATE COLUMN TABLE BASE
("CLIENT" NVARCHAR(3) DEFAULT '000' NOT NULL ,
 "KEY" DECIMAL(21,7) CS_FIXED DEFAULT 0 NOT NULL ,
 "VALUE_FIELD" NVARCHAR(100) DEFAULT '' NOT NULL,
 CONSTRAINT "BASE~0" PRIMARY KEY ("CLIENT", "KEY"));

Then we create a log table to capture keys of changed records from the BASE table:

CREATE COLUMN TABLE LOG_TABLE
("CLIENT" NVARCHAR(3) DEFAULT '000' NOT NULL ,
 "KEY" DECIMAL(21,7) CS_FIXED DEFAULT 0 NOT NULL ,
 "LOG_TIMESTAMP" DECIMAL(21,7) CS_FIXED DEFAULT 0 NOT NULL ,
 "DB_OPERATION" NVARCHAR(1) DEFAULT '' NOT NULL,
 CONSTRAINT "LOG_TABLE~0" PRIMARY KEY ("CLIENT", "KEY", "LOG_TIMESTAMP"));

Here we don't care about value fields, only about keys. I have a trigger code generator depending on the necessity to log changes in specific clients or in all clients. For now, i came up with this solution:

CREATE OR REPLACE TRIGGER "trg_BASE_D"
AFTER DELETE ON "BASE"
REFERENCING OLD ROW AS R
FOR EACH ROW
BEGIN
  INSERT INTO "LOG_TABLE" (CLIENT, KEY, LOG_TIMESTAMP, DB_OPERATION)
  SELECT :R.CLIENT, :R.KEY, TO_NUMBER(TO_CHAR(CURRENT_UTCTIMESTAMP, 'YYYYMMDDHH24MISS.FF7')), 'D'
  FROM DUMMY
  WHERE :R.CLIENT IN ('010', '020');
END;

Of course, similar triggers are created for Insert and Update. Question: does this solution of selecting from dummy have any advantage over more explicit IF solution? That is, do we have any performance implications when using dummy and when using IF?

For comparison:

CREATE OR REPLACE TRIGGER "trg_BASE_D_IF"
AFTER DELETE ON "BASE"
REFERENCING OLD ROW AS R
FOR EACH ROW
BEGIN
  IF :R.CLIENT = '010' OR :R.CLIENT = '020' THEN
    INSERT INTO "LOG_TABLE" (CLIENT, KEY, LOG_TIMESTAMP, DB_OPERATION)
    VALUES (:R.CLIENT, :R.KEY, TO_NUMBER(TO_CHAR(CURRENT_UTCTIMESTAMP, 'YYYYMMDDHH24MISS.FF7')), 'D');
  END IF;
END;

IF automatically results in making SQL script sequential but, at the same time, it uses values directly, without using dummy. Besides, there is nothing here to parallelise as the trigger is ROW-based; WHERE solution doesn't use IF but selects from dummy. How will it impact the trigger performance? Or there will be no difference at all, and it comes down to personal preferences in this case? I prefer a WHERE-based solution as it's easier to generate programmatically; however, both are quite easy to implement, so i'm open to either.

Sorry, i don't have access to an actual HANA DB to run performance tests - i only generate trigger code in ABAP...


Solution

  • If I had to guess I would assume that the procedural IF variant is better, as it does not need to prepare and execute a query - but the difference is likely small and probably smaller than other potential effects.

    What I would rather worry about are bulk inserts into your table with many rows. There looping and performing a singular insert for each row might slow things down significantly. There I guess using the FOR EACH STATEMENT variant with OLD TABLE might be better as the insert in the log table can be done in bulk:

    CREATE OR REPLACE TRIGGER "trg_BASE_D"
    AFTER DELETE ON "BASE"
    REFERENCING OLD TABLE AS R
    FOR EACH STATEMENT
    BEGIN
      INSERT INTO "LOG_TABLE" (CLIENT, KEY, LOG_TIMESTAMP, DB_OPERATION)
      SELECT CLIENT, KEY, TO_NUMBER(TO_CHAR(CURRENT_UTCTIMESTAMP, 'YYYYMMDDHH24MISS.FF7')), 'D'
      FROM :R
      WHERE CLIENT IN ('010', '020');
    END;