Friday, June 7, 2013

Controlling Principal Object Access (POA) table growth

You may notice that the size of the SQL table PrincipalObjectAccess has grown in size and could be using a large percentage of entire database size.

A fix to reduce POA table growth was released in CRM 2011 Update Rollup 6: http://support.microsoft.com/kb/2664150.

Apply Update Rollup 6 and then execute the script documented in the KB article. This script needs to only be executed 1 time after applying Update Rollup 6. Update Rollup 6 and future Update Rollups will fix this known issue going forward.

NOTE: If you install any Update Rollup after Update Rollup 6, without first installing Update Rollup 6, and you have not yet ran the script documented in the resolution steps you will need to execute this script after applying that Update Rollup.

USE []
GO

BEGIN TRY
 BEGIN TRAN t1

  create table #ToDeletePoaEntries
  (
   ObjectId uniqueidentifier,
   Otc int
  )

  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]

  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 @totalDeleted int = 0

  fetch next from entity_cursor
  into @otc, @baseTableName, @primaryKey

  while @@FETCH_STATUS = 0
  begin
   print 'Cleaning up POA for ' + @baseTableName

   declare @deletestatement nvarchar(max)

   -- Insert records to be deleted in [#ToDeletePoaEntries]
   set @deletestatement = '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 @deletestatement

   exec(@deletestatement)
   set @totalCollected = @@ROWCOUNT
   print CAST(@totalCollected as nvarchar(20)) + ' records collected for deletion for ' + @baseTableName

   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

  -- delete all records of the current entity type which don't have corresponding object in the base table
  delete from PrincipalObjectAccess
  from PrincipalObjectAccess poa
  join #ToDeletePoaEntries e on poa.ObjectId = e.ObjectId and poa.ObjectTypeCode = e.Otc

  -- delete PrincipalObjectAccess records

  set @totalDeleted = @@ROWCOUNT
  print CAST(@totalDeleted as nvarchar(20)) + ' records deleted for ' + @baseTableName

 COMMIT TRAN t1
 PRINT 'EXECUTION SUCCEED'
END TRY
BEGIN CATCH
 ROLLBACK TRAN t1
 PRINT 'EXECUTION FAILED :' + ERROR_MESSAGE()
END CATCH

Enable WCF compression to Improve CRM2011 Netowrk Performance

Enable compression using a command line.

1. Open the Command Prompt on the CRM Server.

2. Run the following command:    

%SYSTEMROOT%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /+"dynamicTypes.[mimeType='application/soap%u002bxml; charset=utf-8',enabled='true']" /commit:apphost

3. Reset IIS for the setting to take effect.

Enable compression by manually updating the ApplicationHost.Config

1. On the CRM Server Navigate to: C:\Windows\System32\Inetsrv\Config\applicationHost.config and open it with notepad.

2. Search for the Section: “” and in that section you should fine an entry that looks like this: 

3. Below that, add the following line: 

4. Save the file and reset IIS for the setting to take effect.

Note: You may notice an increase in CPU utilization with compression enabled so be sure to monitor CPU accordingly