SQL Server 2005 Table-valued Function weird performance -


i have huge difference of time execution between 1-minute query , same 1 in table-valued function.

but weired thing running udf (valid) company_id argument gives me result in ~40 seconds , change company_id 12 (valid again), never stops. the execution plans of these 2 queries absolutely not same , of course, long 1 complicated. execution plan between batch version , udf version same , batch version fast...!

if following query "by hand", execution time 1min36s 306 rows:

 select   dbo.date_only(call.date) date,   count(distinct customer_id) new_customers    call  left outer join   dbo.company_new_customers(12, 2009, 2009) new_customers    on dbo.date_only(new_customers.date) = dbo.date_only(call.date)    company_id = 12   , year(call.date) >= 2009   , year(call.date) <= 2009  group   dbo.date_only(call.date) 

i stored same query in function , ran :

select * company_new_customers_count(12, 2009, 2009) 

13 minutes running... , sure never give me result.

yesterday, had exact same infinite-loop-like behaviour during more 4h (so stopped it).

here definition of function:

set ansi_nulls on go set quoted_identifier on go create function company_new_customers_count  (   @company_id int,   @start_year int,  @end_year int ) returns table  return  (  select   dbo.date_only(call.date) date,   count(distinct customer_id) new_customers    call  left outer join   dbo.company_new_customers(@company_id, @start_year, @end_year) new_customers    on dbo.date_only(new_customers.date) = dbo.date_only(call.date)    company_id = @company_id   , year(call.date) >= @start_year   , year(call.date) <= @end_year  group   dbo.date_only(call.date) ) go 

i happy understand going on.

thanks

additional:

definition of company_new_customers:

set ansi_nulls on go set quoted_identifier on go -- ============================================= -- description: create list of new customers of @company_id --          in given period. -- ============================================= create function company_new_customers  (        @company_id int,      @start_year int,     @end_year   int ) returns table  return  (     select         customer_id,         date         (   -- select apparition dates of cutomers before @end_year         select             min(date)       date,             customer_id                     call         join             call_customer on call_customer.call_id = call.call_id                     company_id = @company_id             , year(date) <= @end_year         group             customer_id     ) new_customers             year(date) >= @start_year -- select apparition dates of cutomers after @start_year ) go 

definition of date_only:

set ansi_nulls on go set quoted_identifier on go -- ============================================= -- author:      julio guerra -- create date: 14/10/2010 -- description: return date part of datetime value -- example:         date_only('2010-10-25 13:00:12') returns 2010-10-25 -- ============================================= create function date_only (     @datetime datetime ) returns datetime begin     return dateadd(dd, 0, datediff(dd, 0, @datetime)) end go 

execution plan of select * company_new_customers_count(8, 2009, 2009) alt text

execution plan of select * company_new_customers_count(12, 2009, 2009) alt text

from these query plans looks benefit index (if inferred db schema right):

create index ix_call_company_date on call (company_id, date) 

in general seems standard query optimization problem , table-valued functions aren't making difference here actually.


Comments

Popular posts from this blog

android - Spacing between the stars of a rating bar? -

aspxgridview - Devexpress grid - header filter does not work if column is initially hidden -

c# - How to execute a particular part of code asynchronously in a class -