Episerver Commerce order search is a powerful feature. My colleague Shannon Gray wrote about is long ago https://world.episerver.com/blogs/Shannon-Gray/Dates/2012/12/EPiServer-Commerce-Order-Search-Made-Easy/ , and I myself as well https://world.episerver.com/blogs/Quan-Mai/Dates/2014/10/Order-searchmade-easy/
But because of its power and flexibility, it can be complicated to get right. People usually stop at making the query works. Performance is usually an after thought, as it is only visible on production environment when there are enough requests to bring your database to its knees.
Let me be very clear about it: during my years helping customers with performance issues (and you can guess, that is a lot of customers), order search is one of the most, if not the most common cause of database spikes.
As your commerce database is brought to its knees, your entire website performance suffers. Your response time suffers. Your visitors are unhappy and that makes your business suffer.
But what is so bad about order search?
Order search allows you to find orders by almost any criteria. And to do that, you often join with different tables in the database. Search for orders with specific line items? Join with LineItem table on a match of CatalogEntryId
column. Search for orders with a specific shipping method? Join with Shipment table on a match of ShippingMethodId
etc. etc. SqlWhereClause
and SqlMetaWhereClause
of OrderSearchParameters
are extremely flexible, and that is both a cure, and a curse.
Let’s examine the first example in closer details. The query is easy to write. But don’t you know that there is no index on the CatalogEntryId
column? That means every request to search order, end up in a full table scan of LineItem
.
There are two bad news into that: your LineItem
table usually have many rows already, which makes that scan slow, and resource intensive. And as it’s an ever growing table, the situation only gets worse over time.
That is only a start, and a simple one, because that can be resolved by adding an index on CatalogEntryId
, but there are more complicated cases when adding an index simply can’t solve the problem – because there is no good one. For example if you search for orders with custom fields, but only of type bit
. Bit is essentially the worst type when it comes to index-ability, so your indexes will be much less effective than you want it to be. A full table scan will likely be used.
In short:
Order search is flexible, and powerful. But, “With great power come great responsibility”. Think about what you join on your SqlWhereClause
and SqlMetaWhereClause
statements, and if your query is covered by an index, or if adding an index will make senses in this case (I have a few guidelines here for a good index https://vimvq1987.com/index-or-no-index-thats-the-question/). Or if you can limit the number of the orders you search for.
Your database will thank you, later.