Skip to content
Advertisement

OData $top and PageSize has no impact on web API performance

I currently have a web API for an ASP.net WebApplication that queries a view of all of our Test Data (About 500k rows) in SQL server 2008 R2 which is referenced in the Web API via Entity Framework

JavaScript

Filtering Data has acceptable performance, here is the client side code I am using to debug the Web API:

JavaScript

This Query:

“../api/TestData?$filter=DeviceTypeID eq 2 and DevicePartNumberID eq 74 and TestDateSmall gt 2017-01-01T23:59:59.99Z”

returns 78575 rows in 21 seconds

compared to TSQL:

JavaScript

which takes 13 seconds for the same 78575 rows

I understand the increased time from overhead converting the data to json adding a few seconds. My biggest issue is when selecting the top N rows in Odata:

“../api/TestData?$filter=DeviceTypeID eq 2 and DevicePartNumberID eq 74 and TestDateSmall gt 2017-01-01T23:59:59.99Z&$top=100”

that query takes about 16 seconds to return the 100 rows, I believe that the extra time I have saved is just from the smaller payload.

Doing the same using TSQL:

JavaScript

returns the 100 rows in 1 second (it can also do 10000 rows in 5 seconds)

My guess is that OData isn’t taking the top 100 rows until after the Filter operation completes on the SQL database. I have also tried moving “$top100” before the filter and end up with the same results.

I have also tried setting the PageSize of the web API to 100 like so:

JavaScript

But that has no affect on performance.

Anyone know what I might be missing or doing wrong that might be causing such a big performance hit? Or is this a disadvantage of Odata?

Thanks.

Edit 1: I captured the SQL generated from the Entity Framework, I also replaced the column names with * for readability purposes. It also orders by all of the columns which I omitted. It definitely looks like it isn’t properly optimized because it selects almost everything 3 times.

JavaScript

Edit 2:

It seems the multiple selects are fine, its the ordering that kills performance. Now I just need to stop it from ordering everything.

Edit 3:

I sped things up a lot by disabling “EnsureStableOrdering” after reading this post (Entity framework with OData(Web API) is sending Order By clause By default to Sql Query)

JavaScript

Now it only takes a second or less to return 100 rows. Sorting is slow but that is just an issue with the my indexes and view not OData.

Also the Generated SQL now looks like this:

JavaScript

Advertisement

Answer

The answer is in the post but I’ll add it here too.

Edit 3:

I sped things up a lot by disabling “EnsureStableOrdering” after reading this post (Entity framework with OData(Web API) is sending Order By clause By default to Sql Query)

JavaScript

Now it only takes a second or less to return 100 rows. Sorting is slow but that is just an issue with my indexes and view not OData.

Also the Generated SQL now looks like this:

JavaScript
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement