views:

65

answers:

1

I'm using LinqToSql to query a small, simple SQL Server CE database.

I've noticed that any operations involving sub-properties are disappointingly slow.

For example, if I have a Customer table that is referenced by an Order table, LinqToSql will automatically create an EntitySet<Order> property. This is a nice convenience, allowing me to do things like Customer.Order.Where(o => o.ProductName = "Stopwatch"), but for some reason, SQL Server CE hangs up pretty bad when I try to do stuff like this. One of my queries, which isn't really that complicated takes 3-4 seconds to complete.

I can get the speed up to acceptable, even fast, if I just grab the two tables individually and convert them to List<Customer> and List<Order>, then join then manually with my own query, but this requires a lot of extra code. LinqToSql generates these EntitySet<T> properties automatically--I'd like to use them.

So, how can I improve the performance? For example, are there any DataContext options that would help?

Note: My database in its initial state is only about 250K and I don't expect it to grow to more than 1-2Mb. So, it's not like there are a lot of records.


Update

Here are the table definitions for the example I used in my question:

create table Order
(
    Id int identity(1, 1) primary key,
    ProductName ntext null,
    Quantity int null
)

create table Customer
(
    Id int identity(1, 1) primary key,
    OrderId int null references Order (Id)
)
+1  A: 

I've not used SQL Server CE with Linq to SQL before, but with such a small DB, my gut tells me the performance issue has more to do with poor query optimization than disk access.

Try getting the SQL query from your Linq to SQL objects to see what might be happening. Perhaps run those queries manually against the CE database to see how they perform.

It's very possible that just adding the correct indexes will solve the problem.

You might also try LinqToSQL Profiler. http://l2sprof.com/

Jeff Schumacher
Jeff, thanks. Looking at the actual SQL query helped me figure out the problem. Turns out, one property on the object I was populating in my `select` clause was causing the bad performance. When I commented it out, though, it didn't have any effect on the SQL query! I'm not sure exactly why, but I think it's because the property is a `System.Windows.Media.Brush`, which doesn't have a SQL equivalent. Anyway, if I moved the logic to set the brush to a separate foreach loop, the time to process the query dropped from ~3500ms to ~100ms. Do you have an explanation for this?
DanM
That's very interesting. I wonder if it was something like an internal exception being thrown with every row when Linq to SQL was trying to match up the types and unable to find a match. Difficult to tell. You could step into the debugger symbols for the LinqToSQL methods if you're really interested in finding out why. http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx
Jeff Schumacher