views:

259

answers:

3

We've recently started using complied queries in order to improve performance on our Linq to SQL setup. There are several queries that always take multiple seconds to run the first time take under a second in subsequent runs. This appears to be because the compilation doesn't actually take place until the call is made the first time.

Is there an easy way to force this compilation to happen during the compilation of the program or at the very least during startup?

EDIT: So from the comments I'm seeing it looks like linq queries are definitely not compiled until the call is made. Righ now I'm writing my queries like this:

static readonly Func<DataContext, int, IQueryable<Item>> getByPLUComp =
    CompiledQuery.Compile<DataContext, int, IQueryable<Item>>((db, PLU) =>
            from i in db.Items
            where i.IntPLU == PLU && i.Terminated == null
            select i);

I have a bunch of these static readonly Funcs floating around. Is there an easy way I can have my program run around and initialize them on startup so the cost is incurred there rather than during regular use?

EDIT 2: One last try before I give up on this question. To fix this problem I've just added calls to the compiled queries during the initialization of my program. For example:

public void Initialize()
{
    DataContext db = new DataContext();
    getByPLUComp(db, 0);
}

Is there a more elegant way to force compilation without just running the query and throwing away the results?

A: 

The server need to be the query plan on the first execuation, it then uses the cached plan for subsequent executions.

Paul Creasey
+1  A: 

The database will be caching 2 things when the SQL is executed:

  1. execution plan
  2. data

The execution plan will remain in the cache for subsequent calls for that same query until it "expires". However, it's the data cache that generally makes the biggest difference in performance as the data is kept in memory so subsequent calls don't need to access the disk to get it.

AdaTheDev
This is a very small amount of data and even when the data changes the time for the call does not suddenly increase. Is my problem on the sql server side then?
Mykroft
I would think so, this is where the query is actually executed. I'd get SQL Profiler running, monitor the calls going in. The query could be inefficient - I'd be checking what SQL is actually being executed, check the execution plan. If it's really inefficient/indexes lacking etc, then that could be why the first run is noticeably slower with even a small amount of returned data.
AdaTheDev
I was under the impression that the reason these calls took so long was due to the time taken to convert linq into sql not the execution of the sql itself.
Mykroft
I don't actually know how much of a hit there is when converting linq to sql. Looking at CompiledQuery class, it states that compilation does only happen when the query is first executed, as you thought: http://msdn.microsoft.com/en-us/library/system.data.linq.compiledquery.aspx
AdaTheDev
A: 

Sql Cashes data the first time wich will improve the other runs. . . You could make script that runs though the calls so that they will be cashed. You could ad this to the installation process. . . . That may work.

You could make a table that updates the information needed into it. That way when you need the information its readly available. (if there are alot of processing on bringing the data together)

Hazior