Archive

Posts Tagged ‘PrincipalObjectAccess’

Maintain performance by monitoring shared records

September 25, 2012 1 comment

Let me just give you a background on Sharing before we go into details.

Whenever a record is shared against a User or a Team, CRM will be tracking those entries in PincipalObjectAccess table and same will be queried using FilteredView.

If we see the FilteredView definition we can find how CRM uses this PincipalObjectAccess table.

-- object shared to the user
or
[Account].[AccountId] in
(
select  POA.ObjectId from PrincipalObjectAccess POA
join SystemUserPrincipals sup (NOLOCK) on POA.PrincipalId = sup.PrincipalId
where sup.SystemUserId = u.SystemUserId and
POA.ObjectTypeCode = 1 and
((POA.AccessRightsMask | POA.InheritedAccessRightsMask) & 1)=1
)

The code snippet above was picked from FilteredAccount’s where condition. Here this view is getting the records by querying the PrincipalObjectAccess table

And it’s a known fact that POA is to cause performance bottlenecks.  POA is one of the reasons why complicated business unit structures and extensive sharing is not recommended.

Refer to Microsoft Support article wherein we get the symptoms of Timeout issues. The large is the POA table size the more is the problems list.

Please refer to a nice article on “Why Large-Scale Sharing is Bad

Here are some queries by which you can track and monitor how the organization sharing is being handled.

–Get the total number of shared records

SELECT COUNT(0) FROM PrincipalObjectAccess

 –Get the total number of shared records grouped by Entity

SELECT  EV.NAME AS [ENTITY NAME],COUNT(POA.OBJECTTYPECODE) AS [RECORDS COUNT]
FROM PRINCIPALOBJECTACCESS POA
INNER JOIN ENTITYLOGICALVIEW EV ON EV.OBJECTTYPECODE = POA.OBJECTTYPECODE
GROUP BY EV.NAME
ORDER BY 2 DESC

 –Get the total number of shared records grouped by User

SELECT  SU.FULLNAME AS [USER NAME],COUNT(POA.OBJECTTYPECODE) AS [RECORDS COUNT]
FROM PRINCIPALOBJECTACCESS POA
INNER JOIN SYSTEMUSER SU ON POA.PRINCIPALID= SU.SYSTEMUSERID
GROUP BY SU.FULLNAME
ORDER BY 2 DESC

–Get the total number of shared records grouped by Entity and User

SELECT  SU.FULLNAME AS [USER NAME],EV.NAME AS [ENTITY NAME],COUNT(POA.OBJECTTYPECODE) AS [RECORDS COUNT]
FROM PRINCIPALOBJECTACCESS POA
INNER JOIN SYSTEMUSER SU ON POA.PRINCIPALID= SU.SYSTEMUSERID
INNER JOIN ENTITYLOGICALVIEW EV ON EV.OBJECTTYPECODE = POA.OBJECTTYPECODE
GROUP BY SU.FULLNAME,EV.NAME
ORDER BY 1

Refer to Support Article on controlling PrincipalObjectAccess table growth and cleaning it up

Update Rollup 6 and later will clean the POA table by deleting the unshared records.

Hope this helps 🙂