Feb
18

SMLets – Performance Tip – TypeProjections

By

When using smlets (smlets.codeplex.com) to work with Service Manager using PowerShell, small details can have huge impact on performance.

Server side vs. Client side filtering

The number one thing is to use server side filtering as far as possible. This has been described before but cannot be told too many times.

Example of client side filtering:

?View Code POWERSHELL
$class = Get-SCSMclass system.workitem.incident$ 
Get-SCSMObject -class $class|?{$_.Title -like '*printer*'}

Example of server side filtering:

?View Code POWERSHELL
$class = Get-SCSMclass system.workitem.incident$
Get-SCSMObject $class -Filter "Title -like *printer*"

In my test lab the server side filtering above is 50 times faster than client side. The reason for that is that client side filtering in the example above, in fact means bringing over all objects of the specific class to the client side and finding the matches there. Not a good idea!

Read more about the gain and tips about server side filtering in these excellent blog posts from Travis Wright and Jim Truher:
Properly Querying SCSM Using SMLets Get-SCSMObject cmdlet
Retrieving projection data with PowerShell

Choosing the lighter type projection

What I want to add to the above is how choosing the proper type projection will affect the performance.

As an example, let’s say we want to retrieve all Incidents that are currently Active and Un-Assigned (assigned to user is not set).

We can do this by using the following PowerShell commands:

?View Code POWERSHELL
#Get type projection
$IncidentProjection = Get-SCSMTypeProjection System.WorkItem.Incident.ProjectionType$
#Create criteria
$criteria = new-object $CTYPE $cc,$IncidentProjection.__Base,$IncidentProjection.managementgroup
#Get incidents matching the criteria
$incidents = Get-SCSMObjectProjection -Criteria $criteria

Note: I cut out the part of defining the criteria “$cc”, you can find it in the download available in the bottom of the post.

Depending on which type projection you choose the time for execution of the commands can differ greatly. The reason for this is that different type projections bring a different amount of data back from the server. A type projection is a definition of what data you want to wrap around the seed class instance (in this case the Incident). When choosing which type projection to use we have to think about how we want to define the criteria and which data we want to retrieve. In our example above we just want to see which incidents are Active and Un-assigned. This basically means that we only require a type projection (read more about type projections here) that has the seed class “Incident” and has one component, the AssignedUser. Let’s look at the effect of choosing two different type projections in the example above.

To see which type projections are available for a specific type you can use the following command:

?View Code POWERSHELL
Get-scsmtypeprojection|?{$_.TargetType.Name -eq "System.WorkItem.Incident"}

Note: Client side filtering is perfectly fine in usage like this of course. Another great way to study type projections is to export management packs and look at the xml directly. Also, if you do not find a suitable type projection you can also define your own, but that’s a different story.

After looking at the type projections let’s say that we choose to use the one called “System.WorkItem.Incident.ProjectionType” since this one contains all the components we’ll ever need. Actually it’s the projection that is used out of the box for the Incident form, which means it contains all the components used by the form like: Assigned User, Primary User, Activities, Affected User etc.

Executing the query for all Incidents with status Active which are Un-Assigned, using the type projection above, in my lab environment (over a medium slow connection) takes about 30s.

Now we might be perfectly fine with that, but let’s take a look at what would happen if we would have chosen a “lighter” type projection (fewer components wrapping the incident). As discussed earlier this scenario really only required one component, the AssignedUser, since we’re using the AssignedUser in our criteria.

The out-of-the-box type projection that has the least components and includes the AssignedUser is the projection called “System.WorkItem.Incident.View.ProjectionType”. This projection actually only contains two components: AssignedUser and AffectedUser. Using this projection for the same query for data as the previous, with the same setup takes 10s.

So by choosing a more suitable type projection we managed to cut two thirds of the time used for retrieving the incidents we were looking for.

So remember folks:

  • Use server side filtering
  • Use the type projection with the least components that fulfill your needs.
    Based on components used by your criteria and what data you want to retrieve.

One last thing, when creating views in Service Manager you can use the exact same reasoning regarding which components are required to achieve as good performance as possible. This has been described on its own in this great blog post by Travis Wright: Why is My Custom Incident View So Slow?

You can download my measurement script here: smletsDataQueryTest.ps1

Leave a Reply