Current Position:Home > Performance In Simple Scenarios

Performance In Simple Scenarios

Update:10-11Source: network consolidation
Advertisement
I have done some performance testing to see if asynchronous triggers performs any better than synchronous triggers in a simple audit scenario -- capturing record snapshots at insert, update and delete events to a separate database within the same instance of SQL Server.
Synchronous triggers performed 50% better than asynchronous triggers; this was with conversation reuse and the receive queue activation turned off, so the poor performance was just in the act of forming and sending the message, not receiving and processing.  This was not necessarily surprising to me, and yet I have to wonder under what conditions would we see real performance benefits for audit scenarios.
I am interested if anyone has done similar testing, and if they received similar or different results.  If anyone had conditions where asynchronous triggers pulled ahead for audit scenarios, I would really like to hear back from them.  I invite any comments or suggestions for better performance.
The asynchronous trigger:
Code Snippet
ALTER TRIGGER TR_CUSTOMER_INSERT ON DBO.CUSTOMER
FOR INSERT AS
BEGIN
  DECLARE
    @CONVERSATION UNIQUEIDENTIFIER ,
    @MESSAGE XML ,
    @LOG_OPERATION CHAR(1) ,
    @LOG_USER VARCHAR(35) ,
    @LOG_DATE DATETIME;
  SELECT TOP(1)
    @CONVERSATION = CONVERSATION_HANDLE ,
    @LOG_OPERATION = 'I' ,
    @LOG_USER = USER() ,
    @LOG_DATE = GETDATE()
  FROM SYS.CONVERSATION_ENDPOINTS;
  SET @MESSAGE =
  ( SELECT
      CUST_ID = NEW.CUST_ID ,
      CUST_DESCR = NEW.CUST_DESCR ,
      CUST_ADDRESS = NEW.CUST_ADDRESS ,
      LOG_OPERATION = @LOG_OPERATION ,
      LOG_USER = @LOG_USER ,
      LOG_DATE = @LOG_DATE
    FROM INSERTED NEW
    FOR XML AUTO );
  SEND ON CONVERSATION @CONVERSATION
    MESSAGE TYPE CUSTOMER_LOG_MESSAGE ( @MESSAGE );
END;
The synchronous trigger:
Code Snippet
ALTER TRIGGER TR_CUSTOMER_INSERT ON DBO.CUSTOMER
FOR INSERT AS
BEGIN
  DECLARE
    @LOG_OPERATION CHAR(1) ,
    @LOG_USER VARCHAR(15) ,
    @LOG_DATE DATETIME;
  SELECT
    @LOG_OPERATION = 'I' ,
    @LOG_USER = USER() ,
    @LOG_DATE = GETDATE()
  INSERT INTO SALES_LOG.DBO.CUSTOMER
  SELECT
    CUST_ID = NEW.CUST_ID ,
    CUST_DESCR = NEW.CUST_DESCR ,
    CUST_ADDRESS = NEW.CUST_ADDRESS ,
    LOG_OPERATION = @LOG_OPERATION ,
    LOG_USER = @LOG_USER ,
    LOG_DATE = @LOG_DATE
  FROM INSERTED NEW
END;

The Best Answer

Advertisement
Synchronous audit has to do one database write (one insert). Asynchronous audit has to do at least an insert and an update (the SEND)  plus a delete (the RECEIVE) and an insert (the audit itself), so that is 4 database writes. If the destination audit service is remote, then the sys.transmission_queue operations have to be added (one insert and one delete). So clearly there is no way asynchronous audit can be on pair with synchronous audit, there are at least 3 more writes to complete. And that is neglecting all the reads (like looking up the conversation handle etc) and all the marshaling/unmarshaling of the message (usually some fairly expensive XML processing).
Within one database the asynchronous pattern is apealing when the trigger processing is expensive (so that the extra cost of going async is negligible) and reducing the original call response time is important. It could also help if the audit operations create high contention and defering the audit reduces this. Some more esoteric reasons is when asynchronous processing is desired for architecture reasons, like the posibility to add a workflow triggered by the original operation and desire to change this workflow on-the-fly without impact/down time (eg. more consumers of the async message are added, the message is schreded/dispatched to more processing apps and triggers more messages downstream etc etc).
If the audit is between different databases even within same instance then the problem of availabilty arrises (audit table/database may be down for intervals, blocking the orginal operations/application).
If the audit is remote (different SQL Server isntances) then using Service Broker solves the most difficult problem (communication) in addition to asynchronicity and availability, in that case the the synchrnous pattern (e.g. using a linked server) is really a bad choice.