Microsoft Dynamics CRM PrincipalObjectAccess POA Temizliği

Microsoft Dynamics CRM içerisinde bildiğiniz üzere oluşmuş olan kayıtları çeşitli kullanıcı ve takımlar ile paylaşabiliyorsunuz. Crm üzerinde bulunan herhangi bir kaydı herhangi bir kullanıcı ya da takım ile paylaşırsanız ya da atama işlemi yaparsanız bu kayıt için PrincipalObjectAccess tablosuna kayıt atılmaktadır. Microsoft Dynamics CRM PrincipalObjectAccess bazen gereksiz yere dosyalarla dolmaktadır. Gereksiz yere dolan POA tablosu performans kaybına yol açacaktır.

Microsoft Dynamics CRM PrincipalObjectAccess POA Temizliği

Microsoft tarafından belirtilmiş olan POA temizleme sorgusunu belli aralıklar ile çalıştırmak gerekmektedir. Microsoft’un sorgusuna bu adresten erişebilirsiniz. Sorgu:

--Official Microsoft Query to cleanup PrincipalObjectAccess. Article Link is below 
--https://support.microsoft.com/en-ca/help/2664150/how-to-control-principalobjectaccess-table-growth-in-microsoft-dynamic 
USE kfh_mscrm 

go 

BEGIN try 
    BEGIN TRAN t1 

    IF NOT EXISTS (SELECT * 
                   FROM   sys.sysobjects 
                   WHERE  id = Object_id(N'[dbo].[ToDeletePOAEntries]') 
                          AND Objectproperty(id, N'IsUserTable') = 1) 
      CREATE TABLE todeletepoaentries 
        ( 
           objectid UNIQUEIDENTIFIER, 
           otc      INT 
        ) 

    IF NOT EXISTS (SELECT * 
                   FROM   sys.sysindexes si 
                          INNER JOIN sys.sysobjects so 
                                  ON si.id = so.id 
                   WHERE  so.id = Object_id(N'[dbo].[ToDeletePoaEntries]') 
                          AND Objectproperty(so.id, N'IsUserTable') = 1 
                          AND si.NAME LIKE '%mainindex%') 
      CREATE UNIQUE NONCLUSTERED INDEX [mainindex] 
        ON [dbo].[ToDeletePoaEntries] ( [objectid] ASC, [otc] ASC ) 
        WITH (statistics_norecompute = OFF, sort_in_tempdb = OFF, ignore_dup_key 
      = 
      OFF 
      , drop_existing = OFF, online = OFF, allow_row_locks = ON, 
      allow_page_locks = 
      ON 
      ) ON [PRIMARY] 

    ----- Insert records to be deleted in ToDeletePoaEntries 
    -- go through all user-owned entities which are not replicated and don't support duplicate detection 
    DECLARE entity_cursor CURSOR local forward_only read_only FOR 
      SELECT DISTINCT e.objecttypecode, 
                      e.basetablename, 
                      a.physicalname 
      FROM   entityview e 
             INNER JOIN attributeview a 
                     ON e.entityid = a.entityid 
                        AND a.ispkattribute = 1 
      WHERE  e.isreplicated = 0 
             AND e.isduplicatechecksupported = 0 
             AND e.ownershiptypemask & 1 = 1 

    OPEN entity_cursor 

    DECLARE @baseTableName SYSNAME 
    DECLARE @otc NVARCHAR(20) 
    DECLARE @primaryKey SYSNAME 
    DECLARE @totalCollected INT = 0 
    DECLARE @currentCollected INT 
    DECLARE @tempRowCount INT = 0 
    DECLARE @collectstatement NVARCHAR(max) 

    FETCH next FROM entity_cursor INTO @otc, @baseTableName, @primaryKey 

    WHILE @@FETCH_STATUS = 0 
      BEGIN 
          PRINT 'Cleaning up POA for ' + @baseTableName 

          SET @currentCollected = 0 
          SET @collectstatement = 'insert into ToDeletePoaEntries(ObjectId, Otc)  select distinct poa.ObjectId, poa.ObjectTypeCode  from PrincipalObjectAccess poa left join ' + @baseTableName 
                                  + ' e on poa.ObjectId = e.' + @primaryKey 
                                  + ' where e.' + @primaryKey 
                                  + ' is null and poa.ObjectTypeCode = ' + @otc; 

          PRINT @collectstatement 

          EXEC(@collectstatement) 

          SET @tempRowCount = @@ROWCOUNT 
          SET @currentCollected = @currentCollected + @tempRowCount 

          PRINT Cast(@currentCollected AS NVARCHAR(20)) 
                + ' records collected for ' + @baseTableName 

          SET @totalCollected = @totalCollected + @currentCollected 

          FETCH next FROM entity_cursor INTO @otc, @baseTableName, @primaryKey 
      END 

    CLOSE entity_cursor 

    DEALLOCATE entity_cursor 

    PRINT Cast(@totalCollected AS NVARCHAR(20)) 
          + ' total records collected' 

    -- Delete query 
    -- This scripts cleans up orphaned POA records for selected entities 
    DECLARE @deleteBatchSize INT = 50000 
    DECLARE @deleteBatchSizeNVarChar NVARCHAR(10) = Cast( 
            @deleteBatchSize AS NVARCHAR(10)) 
    DECLARE @totalDeleted INT = 0 
    DECLARE @currentDeleted INT 
    DECLARE @deletestatement NVARCHAR(max) 

    SET @currentDeleted = 0 
    SET @tempRowCount = 0 
    -- delete all records of the current entity type which don't have corresponding object in the base table
    SET @deletestatement = 'delete top (' + @deleteBatchSizeNVarChar 
                           + 
') from PrincipalObjectAccess from PrincipalObjectAccess poa join ToDeletePoaEntries e on poa.ObjectId = e.ObjectId and poa.ObjectTypeCode = e.Otc' 

    PRINT @deletestatement 

    -- delete PrincipalObjectAccess records in batches 
    EXEC(@deletestatement) 

    SET @tempRowCount = @@ROWCOUNT 
    SET @currentDeleted = @currentDeleted + @tempRowCount 

    WHILE @tempRowCount = @deleteBatchSize 
      BEGIN 
          EXEC(@deletestatement) 

          SET @tempRowCount = @@ROWCOUNT 
          SET @currentDeleted = @currentDeleted + @tempRowCount 

          PRINT Cast(@currentDeleted AS NVARCHAR(20)) 
                + ' records deleted ' 
                + Cast(Getutcdate() AS NVARCHAR(50)) 
      --cleanup 
      END 

    COMMIT TRAN t1 

    -- Cleanup 
    DROP TABLE [dbo].[todeletepoaentries] 

    PRINT 'EXECUTION SUCCEED' 
END try 

BEGIN catch 
    ROLLBACK TRAN t1 

    -- Cleanup 
    DROP TABLE [dbo].[todeletepoaentries] 

    PRINT 'EXECUTION FAILED :' + Error_message() 
END catch 

Crm sisteminde herhangi bir amaçla paylaşılan ya da ataması yapılan kayıtların atıldığı PrincipleObjectAccess tablosu zamanla geçerliliğini yitirmektedir. Paylaşılmış olan bir kaydın silinmesi ya da paylaşılan Crm kullanıcılarından birinin ya da bir kaçının artık sistemde aktif olmaması bu tablonun geçerliliğini yitirmesine yol açmaktadır. Belli aralıklarla bu kirli verileri temizlemek gerekmektedir.

Aylık olarak POA temizleme sorgusunu çalıştıran bir SQL Job oluşturarak Crm’in performansını kaybetmesinin önüne geçebilirsiniz. Sorguyu güzelcene analiz ettikten sonra kendi ihtiyaçlarınıza karşılık gelecek şekilde sorguyu güncelleyebilirsiniz. Sorgunun güncellenmesi konusunda dikkatli olmanızı öneririm çünkü bu sorgu, Microsoft tarafından optimum değerler ile oluşturulmuştur. Ancak bazı Crm kullanım tiplerinde bu sorgudaki bazı sihirli rakamların güncellenmesi gerekmektedir.

POA temizlik işleminin yanı sıra Crm async işlemlerin temizliğini de performans iyileştirmek için unutmamak gerekmektedir. Her 2 işlemi de yaparak Crm’in performansında artış yaşayabilirsiniz.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir