Home All Groups Group Topic Archive Search About

Why run time double in a script?

Author
23 Jun 2006 8:30 PM
nick
I have table value UDFs. It takes about 2.5 minutes when I execute
select * from dbo.myudf('...')

I have a stored procedure to run thousands of the UDFs as dynaml SQL:

@sql = 'insert into @tablevalue select '+.....+' from dbo.myudf('+...+'...)'
exec (@sql)

However, it takes about 4.7 minutes to run the same query. Does the dynamal
sql cause the slowness? Or how much will checkpoint help? I already set the
database as simple Recovery model.

Author
23 Jun 2006 8:34 PM
Aaron Bertrand [SQL Server MVP]
Show quote
>I have table value UDFs. It takes about 2.5 minutes when I execute
> select * from dbo.myudf('...')
>
> I have a stored procedure to run thousands of the UDFs as dynaml SQL:
>
> @sql = 'insert into @tablevalue select '+.....+' from
> dbo.myudf('+...+'...)'
> exec (@sql)
>
> However, it takes about 4.7 minutes to run the same query. Does the
> dynamal
> sql cause the slowness? Or how much will checkpoint help? I already set
> the
> database as simple Recovery model.

Well, you're writing the data into another table, which is not the same as
just select *.

As much as you might want to believe otherwise, it is not necessarily the
case that your table variable is created solely in memory.  And even if it
were, it is not necessarily the case that you get the table population 'for
free'... e.g. it will consume resources to do that.
Author
23 Jun 2006 8:48 PM
nick
The data written in table variable is in fact not big. About 200K rows at
most with only two float columns and one varchar(100) column....

Show quote
"Aaron Bertrand [SQL Server MVP]" wrote:

> >I have table value UDFs. It takes about 2.5 minutes when I execute
> > select * from dbo.myudf('...')
> >
> > I have a stored procedure to run thousands of the UDFs as dynaml SQL:
> >
> > @sql = 'insert into @tablevalue select '+.....+' from
> > dbo.myudf('+...+'...)'
> > exec (@sql)
> >
> > However, it takes about 4.7 minutes to run the same query. Does the
> > dynamal
> > sql cause the slowness? Or how much will checkpoint help? I already set
> > the
> > database as simple Recovery model.
>
> Well, you're writing the data into another table, which is not the same as
> just select *.
>
> As much as you might want to believe otherwise, it is not necessarily the
> case that your table variable is created solely in memory.  And even if it
> were, it is not necessarily the case that you get the table population 'for
> free'... e.g. it will consume resources to do that.
>
>
>
Author
23 Jun 2006 8:52 PM
Aaron Bertrand [SQL Server MVP]
> The data written in table variable is in fact not big.

While size matters, it is not everything.  As Alexander suggested, you are
having a hard time diagnosng the problem because you changed two things at
once.  (1) you turned a static query into dynamic SQL, and (2) you added
population of a table variable.  This makes it very difficult to determine
what change introduced the slowness.  Make one change at a time...

A
Author
23 Jun 2006 8:56 PM
Mike C#
It's still costlier to INSERT data into a table than to SELECT data from a
table.  SQL has to ensure the ATOMicity of INSERTs, log them, update any
indexes, possibly re-arrange the table if you have a clustered index,
maintain locks, etc., etc., etc.  SELECT doesn't have as much overhead.

Show quote
"nick" <n***@discussions.microsoft.com> wrote in message
news:E589C286-4C4D-4F62-9E28-DFB269707B56@microsoft.com...
> The data written in table variable is in fact not big. About 200K rows at
> most with only two float columns and one varchar(100) column....
>
> "Aaron Bertrand [SQL Server MVP]" wrote:
>
>> >I have table value UDFs. It takes about 2.5 minutes when I execute
>> > select * from dbo.myudf('...')
>> >
>> > I have a stored procedure to run thousands of the UDFs as dynaml SQL:
>> >
>> > @sql = 'insert into @tablevalue select '+.....+' from
>> > dbo.myudf('+...+'...)'
>> > exec (@sql)
>> >
>> > However, it takes about 4.7 minutes to run the same query. Does the
>> > dynamal
>> > sql cause the slowness? Or how much will checkpoint help? I already set
>> > the
>> > database as simple Recovery model.
>>
>> Well, you're writing the data into another table, which is not the same
>> as
>> just select *.
>>
>> As much as you might want to believe otherwise, it is not necessarily the
>> case that your table variable is created solely in memory.  And even if
>> it
>> were, it is not necessarily the case that you get the table population
>> 'for
>> free'... e.g. it will consume resources to do that.
>>
>>
>>
Author
23 Jun 2006 8:45 PM
Alexander Kuznetsov
nick wrote:
> I have table value UDFs. It takes about 2.5 minutes when I execute
> select * from dbo.myudf('...')
>
> I have a stored procedure to run thousands of the UDFs as dynaml SQL:
>
> @sql = 'insert into @tablevalue select '+.....+' from dbo.myudf('+...+'...)'
> exec (@sql)
>
> However, it takes about 4.7 minutes to run the same query. Does the dynamal
> sql cause the slowness? Or how much will checkpoint help? I already set the
> database as simple Recovery model.

you probably need to separate the UDF execution time and the time to
insert into a table variable. I would suggest that you materialize the
output of the UDF into a staging table, populate the table variable
from the staging table and see how much time that would take.
Author
23 Jun 2006 8:56 PM
nick
I rechecked the rows returned by the UDF It's actually only 20 rows.

Show quote
"Alexander Kuznetsov" wrote:

>
> nick wrote:
> > I have table value UDFs. It takes about 2.5 minutes when I execute
> > select * from dbo.myudf('...')
> >
> > I have a stored procedure to run thousands of the UDFs as dynaml SQL:
> >
> > @sql = 'insert into @tablevalue select '+.....+' from dbo.myudf('+...+'...)'
> > exec (@sql)
> >
> > However, it takes about 4.7 minutes to run the same query. Does the dynamal
> > sql cause the slowness? Or how much will checkpoint help? I already set the
> > database as simple Recovery model.
>
> you probably need to separate the UDF execution time and the time to
> insert into a table variable. I would suggest that you materialize the
> output of the UDF into a staging table, populate the table variable
> from the staging table and see how much time that would take.
>
>
Author
23 Jun 2006 9:01 PM
Aaron Bertrand [SQL Server MVP]
>I rechecked the rows returned by the UDF It's actually only 20 rows.

Wow, 20 rows takes over two minutes?

If I were in your shoes (and yes, I know I'm not), I think I'd focus on the
model so that the query itself doesn't take so long, instead of worrying
about how to speed it up when I throw a table variable and dynamic SQL on
top of it (both things which will *at best* keep the query time the same,
but more often than not, increase it, in most scenarios).

A
Author
23 Jun 2006 10:24 PM
Erland Sommarskog
nick (n***@discussions.microsoft.com) writes:
> I have table value UDFs. It takes about 2.5 minutes when I execute
> select * from dbo.myudf('...')
>
> I have a stored procedure to run thousands of the UDFs as dynaml SQL:
>
> @sql = 'insert into @tablevalue select '+.....+' from
> dbo.myudf('+...+'...)'
> exec (@sql)
>
> However, it takes about 4.7 minutes to run the same query. Does the
> dynamal sql cause the slowness? Or how much will checkpoint help? I
> already set the database as simple Recovery model.

I don't really see the point of inserting into a table variable in
dynamic SQL...

As the other folks, I would more suspect the INSERT than the dynamic
SQL. When you run the function from the INSERT statement, it will
execute in the context of a transaction. Depending on the isolation
level, this could affect the execution time, particularly if there
is blocking.

You should alo run this several times to make sure. The difference
could be due to natural variation because of the load on the server.

--
Erland Sommarskog, SQL Server MVP, esq***@sommarskog.se

Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
Author
23 Jun 2006 11:42 PM
Mike C#
Based on nick's most recent admission, I'm suspecting a poorly written query
or lack of indexes inside the UDF.

Show quote
"Erland Sommarskog" <esq***@sommarskog.se> wrote in message
news:Xns97EC413B8EC3Yazorman@127.0.0.1...
> nick (n***@discussions.microsoft.com) writes:
>> I have table value UDFs. It takes about 2.5 minutes when I execute
>> select * from dbo.myudf('...')
>>
>> I have a stored procedure to run thousands of the UDFs as dynaml SQL:
>>
>> @sql = 'insert into @tablevalue select '+.....+' from
>> dbo.myudf('+...+'...)'
>> exec (@sql)
>>
>> However, it takes about 4.7 minutes to run the same query. Does the
>> dynamal sql cause the slowness? Or how much will checkpoint help? I
>> already set the database as simple Recovery model.
>
> I don't really see the point of inserting into a table variable in
> dynamic SQL...
>
> As the other folks, I would more suspect the INSERT than the dynamic
> SQL. When you run the function from the INSERT statement, it will
> execute in the context of a transaction. Depending on the isolation
> level, this could affect the execution time, particularly if there
> is blocking.
>
> You should alo run this several times to make sure. The difference
> could be due to natural variation because of the load on the server.
>
> --
> Erland Sommarskog, SQL Server MVP, esq***@sommarskog.se
>
> Books Online for SQL Server 2005 at
> http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
> Books Online for SQL Server 2000 at
> http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
Author
24 Jun 2006 6:31 PM
nick
Ok, let me explain why dynamical SQL and let you know if the query is poor
written.

The UDFs has one or two parameter and return a 20 some rows. The UDF will
calculate the meen value group by a category column. Since SQL Server don't
have aggregete function Mean(), I had to insert to data into a temp/table
variable. I tried write a stored procedure with temp table and create index.
it has the same performance as the UDF i wrote with table variable (Because
UDF doesn't allow temp table). In fact, I defined primary key in the table
varable for index to achieve the same performance.

Unless using SQL 2005 with .Net aggregate function, I don't see a better
solution for mean function.

Why dynamical SQL? there are thousands of the UDFs, and a simple joinning
with the result of the UDF with other tables to get the final result.

I know it's hard since I didn't post all the code. But the UDFs should have
constant speed. And the dynamical SQL doesn't take much time when trying a
single step.

My question why a single step takes only half the time? comparing with the
same step in a loop of thousands.



Show quote
"Mike C#" wrote:

> Based on nick's most recent admission, I'm suspecting a poorly written query
> or lack of indexes inside the UDF.
>
> "Erland Sommarskog" <esq***@sommarskog.se> wrote in message
> news:Xns97EC413B8EC3Yazorman@127.0.0.1...
> > nick (n***@discussions.microsoft.com) writes:
> >> I have table value UDFs. It takes about 2.5 minutes when I execute
> >> select * from dbo.myudf('...')
> >>
> >> I have a stored procedure to run thousands of the UDFs as dynaml SQL:
> >>
> >> @sql = 'insert into @tablevalue select '+.....+' from
> >> dbo.myudf('+...+'...)'
> >> exec (@sql)
> >>
> >> However, it takes about 4.7 minutes to run the same query. Does the
> >> dynamal sql cause the slowness? Or how much will checkpoint help? I
> >> already set the database as simple Recovery model.
> >
> > I don't really see the point of inserting into a table variable in
> > dynamic SQL...
> >
> > As the other folks, I would more suspect the INSERT than the dynamic
> > SQL. When you run the function from the INSERT statement, it will
> > execute in the context of a transaction. Depending on the isolation
> > level, this could affect the execution time, particularly if there
> > is blocking.
> >
> > You should alo run this several times to make sure. The difference
> > could be due to natural variation because of the load on the server.
> >
> > --
> > Erland Sommarskog, SQL Server MVP, esq***@sommarskog.se
> >
> > Books Online for SQL Server 2005 at
> > http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
> > Books Online for SQL Server 2000 at
> > http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
>
>
>
Author
24 Jun 2006 6:33 PM
nick
In fact, I should never mention the dynamical and UDF part. It sounds not
relevent to the problem.
Author
24 Jun 2006 7:40 PM
Steve Kass
nick wrote:

Show quote
>Ok, let me explain why dynamical SQL and let you know if the query is poor
>written.
>
>The UDFs has one or two parameter and return a 20 some rows. The UDF will
>calculate the meen value group by a category column. Since SQL Server don't
>have aggregete function Mean(), I had to insert to data into a temp/table
>variable. I tried write a stored procedure with temp table and create index.
>it has the same performance as the UDF i wrote with table variable (Because
>UDF doesn't allow temp table). In fact, I defined primary key in the table
>varable for index to achieve the same performance.
>
>Unless using SQL 2005 with .Net aggregate function, I don't see a better
>solution for mean function.

>

The SQL aggregate function AVG() calculates the mean.  Just be sure to
coerce
integer values to float or decimal, if you want a non-integer mean of
integer data.

select AVG(1.0*x)
from (
  select 1 as x
  union all
  select 2 as x
  union all
  select 5 as x
) T

Steve Kass
Drew University

Show quote
>Why dynamical SQL? there are thousands of the UDFs, and a simple joinning
>with the result of the UDF with other tables to get the final result.
>
>I know it's hard since I didn't post all the code. But the UDFs should have
>constant speed. And the dynamical SQL doesn't take much time when trying a
>single step.
>
>My question why a single step takes only half the time? comparing with the
>same step in a loop of thousands.
>
>
>
>"Mike C#" wrote:
>

>
>>Based on nick's most recent admission, I'm suspecting a poorly written query
>>or lack of indexes inside the UDF.
>>
>>"Erland Sommarskog" <esq***@sommarskog.se> wrote in message
>>news:Xns97EC413B8EC3Yazorman@127.0.0.1...
>>   
>>
>>>nick (n***@discussions.microsoft.com) writes:
>>>     
>>>
>>>>I have table value UDFs. It takes about 2.5 minutes when I execute
>>>>select * from dbo.myudf('...')
>>>>
>>>>I have a stored procedure to run thousands of the UDFs as dynaml SQL:
>>>>
>>>>@sql = 'insert into @tablevalue select '+.....+' from
>>>>dbo.myudf('+...+'...)'
>>>>exec (@sql)
>>>>
>>>>However, it takes about 4.7 minutes to run the same query. Does the
>>>>dynamal sql cause the slowness? Or how much will checkpoint help? I
>>>>already set the database as simple Recovery model.
>>>>       
>>>>
>>>I don't really see the point of inserting into a table variable in
>>>dynamic SQL...
>>>
>>>As the other folks, I would more suspect the INSERT than the dynamic
>>>SQL. When you run the function from the INSERT statement, it will
>>>execute in the context of a transaction. Depending on the isolation
>>>level, this could affect the execution time, particularly if there
>>>is blocking.
>>>
>>>You should alo run this several times to make sure. The difference
>>>could be due to natural variation because of the load on the server.
>>>
>>>--
>>>Erland Sommarskog, SQL Server MVP, esq***@sommarskog.se
>>>
>>>Books Online for SQL Server 2005 at
>>>http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
>>>Books Online for SQL Server 2000 at
>>>http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
>>>     
>>>
>>
>>   
>>
Author
25 Jun 2006 1:57 AM
nick
mean sometimes means average. What I've implemented is median....

Show quote
"Steve Kass" wrote:

>
>
> nick wrote:
>
> >Ok, let me explain why dynamical SQL and let you know if the query is poor
> >written.
> >
> >The UDFs has one or two parameter and return a 20 some rows. The UDF will
> >calculate the meen value group by a category column. Since SQL Server don't
> >have aggregete function Mean(), I had to insert to data into a temp/table
> >variable. I tried write a stored procedure with temp table and create index.
> >it has the same performance as the UDF i wrote with table variable (Because
> >UDF doesn't allow temp table). In fact, I defined primary key in the table
> >varable for index to achieve the same performance.
> >
> >Unless using SQL 2005 with .Net aggregate function, I don't see a better
> >solution for mean function.
> > 
> >
>
> The SQL aggregate function AVG() calculates the mean.  Just be sure to
> coerce
> integer values to float or decimal, if you want a non-integer mean of
> integer data.
>
> select AVG(1.0*x)
> from (
>   select 1 as x
>   union all
>   select 2 as x
>   union all
>   select 5 as x
> ) T
>
> Steve Kass
> Drew University
>
> >Why dynamical SQL? there are thousands of the UDFs, and a simple joinning
> >with the result of the UDF with other tables to get the final result.
> >
> >I know it's hard since I didn't post all the code. But the UDFs should have
> >constant speed. And the dynamical SQL doesn't take much time when trying a
> >single step.
> >
> >My question why a single step takes only half the time? comparing with the
> >same step in a loop of thousands.
> >
> >
> >
> >"Mike C#" wrote:
> >
> > 
> >
> >>Based on nick's most recent admission, I'm suspecting a poorly written query
> >>or lack of indexes inside the UDF.
> >>
> >>"Erland Sommarskog" <esq***@sommarskog.se> wrote in message
> >>news:Xns97EC413B8EC3Yazorman@127.0.0.1...
> >>   
> >>
> >>>nick (n***@discussions.microsoft.com) writes:
> >>>     
> >>>
> >>>>I have table value UDFs. It takes about 2.5 minutes when I execute
> >>>>select * from dbo.myudf('...')
> >>>>
> >>>>I have a stored procedure to run thousands of the UDFs as dynaml SQL:
> >>>>
> >>>>@sql = 'insert into @tablevalue select '+.....+' from
> >>>>dbo.myudf('+...+'...)'
> >>>>exec (@sql)
> >>>>
> >>>>However, it takes about 4.7 minutes to run the same query. Does the
> >>>>dynamal sql cause the slowness? Or how much will checkpoint help? I
> >>>>already set the database as simple Recovery model.
> >>>>       
> >>>>
> >>>I don't really see the point of inserting into a table variable in
> >>>dynamic SQL...
> >>>
> >>>As the other folks, I would more suspect the INSERT than the dynamic
> >>>SQL. When you run the function from the INSERT statement, it will
> >>>execute in the context of a transaction. Depending on the isolation
> >>>level, this could affect the execution time, particularly if there
> >>>is blocking.
> >>>
> >>>You should alo run this several times to make sure. The difference
> >>>could be due to natural variation because of the load on the server.
> >>>
> >>>--
> >>>Erland Sommarskog, SQL Server MVP, esq***@sommarskog.se
> >>>
> >>>Books Online for SQL Server 2005 at
> >>>http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
> >>>Books Online for SQL Server 2000 at
> >>>http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
> >>>     
> >>>
> >>
> >>   
> >>
>
Author
25 Jun 2006 3:47 AM
Mike C#
"nick" <n***@discussions.microsoft.com> wrote in message
news:CBDAABBF-F66B-4B05-80A5-30180AE5DC1E@microsoft.com...
> mean sometimes means average. What I've implemented is median....

Ahhh, mean is not the same as median, except that the median in a set with
an even number of members is the mean of the middle two.  I have no idea
what your code looks like since you didn't supply any DDL, DML or anything
else that can be used to help troubleshoot your problem, but to try and
answer your question:  The SQL Server engine is set-based.  It's highly
tuned to perform set-based operations on large quantities of data in one
shot; procedural code very often suffers on SQL Server because of the
emphasis on set-based operations.  I have no idea what you're putting in
your temp table, but here's a simple example of grabbing the median of a
column:

CREATE TABLE #Test (Price NUMERIC(10, 2) NOT NULL PRIMARY KEY)

INSERT INTO #Test (Price)
SELECT 10.20
UNION SELECT 11.40
UNION SELECT 4.30
UNION SELECT 12.50
UNION SELECT 8.30

SELECT SUM(c.Price) / 2.0 AS Median
FROM (
SELECT MAX(a.Price) AS Price
FROM
(
  SELECT TOP 50 PERCENT Price
  FROM #Test
  ORDER BY Price ASC
) a
UNION ALL
SELECT MIN(b.Price)
FROM
(
  SELECT TOP 50 PERCENT Price
  FROM #Test
  ORDER BY Price DESC
) b
) c

DROP TABLE #Test
Author
26 Jun 2006 3:18 PM
nick
This is good to calculate one median in a data set. It's difficult to use it
to calculate multiple medians grouping by some columns....

Show quote
"Mike C#" wrote:

>
> "nick" <n***@discussions.microsoft.com> wrote in message
> news:CBDAABBF-F66B-4B05-80A5-30180AE5DC1E@microsoft.com...
> > mean sometimes means average. What I've implemented is median....
>
> Ahhh, mean is not the same as median, except that the median in a set with
> an even number of members is the mean of the middle two.  I have no idea
> what your code looks like since you didn't supply any DDL, DML or anything
> else that can be used to help troubleshoot your problem, but to try and
> answer your question:  The SQL Server engine is set-based.  It's highly
> tuned to perform set-based operations on large quantities of data in one
> shot; procedural code very often suffers on SQL Server because of the
> emphasis on set-based operations.  I have no idea what you're putting in
> your temp table, but here's a simple example of grabbing the median of a
> column:
>
> CREATE TABLE #Test (Price NUMERIC(10, 2) NOT NULL PRIMARY KEY)
>
> INSERT INTO #Test (Price)
> SELECT 10.20
> UNION SELECT 11.40
> UNION SELECT 4.30
> UNION SELECT 12.50
> UNION SELECT 8.30
>
> SELECT SUM(c.Price) / 2.0 AS Median
> FROM (
>  SELECT MAX(a.Price) AS Price
>  FROM
>  (
>   SELECT TOP 50 PERCENT Price
>   FROM #Test
>   ORDER BY Price ASC
>  ) a
>  UNION ALL
>  SELECT MIN(b.Price)
>  FROM
>  (
>   SELECT TOP 50 PERCENT Price
>   FROM #Test
>   ORDER BY Price DESC
>  ) b
> ) c
>
> DROP TABLE #Test
>
>
>
>
Author
26 Jun 2006 4:47 PM
Mike C#
"nick" <n***@discussions.microsoft.com> wrote in message
news:96026AC0-A18E-4A25-8403-20C56EE1AD86@microsoft.com...
> This is good to calculate one median in a data set. It's difficult to use
> it
> to calculate multiple medians grouping by some columns....

Sorry to hear that doesn't work out for you.  Unfortunately I'm not going to
keep guessing at fixes when you won't even explain the problem, man.  What
you posted right above this sounds like a very simple change to what I
previously posted, but unfortunately I don't have the time or patience to
keep blindly guessing at exactly what you're doing.

Peace
Author
25 Jun 2006 4:37 AM
Steve Kass
Nick,

Here is an efficient way to find a median if you are using SQL Server 2005.
This query gives the median [Freight] for each customer's orders:

select
  CustomerID,
  avg(Freight) as medianFreight
from (
  select
    CustomerID,
    Freight,
    row_number() over (partition by CustomerID order by Freight asc,
OrderID asc) as r1,
    row_number() over (partition by CustomerID order by Freight desc,
OrderID desc) as r2
  from Northwind..Orders
) T
where r1 - r2 between -1 and 1
group by CustomerID
-- Idea from Itzik Ben-Gan's book T-SQL Querying

-- SK

nick wrote:

Show quote
>mean sometimes means average. What I've implemented is median....
>
>"Steve Kass" wrote:
>

>
>>nick wrote:
>>
>>   
>>
>>>Ok, let me explain why dynamical SQL and let you know if the query is poor
>>>written.
>>>
>>>The UDFs has one or two parameter and return a 20 some rows. The UDF will
>>>calculate the meen value group by a category column. Since SQL Server don't
>>>have aggregete function Mean(), I had to insert to data into a temp/table
>>>variable. I tried write a stored procedure with temp table and create index.
>>>it has the same performance as the UDF i wrote with table variable (Because
>>>UDF doesn't allow temp table). In fact, I defined primary key in the table
>>>varable for index to achieve the same performance.
>>>
>>>Unless using SQL 2005 with .Net aggregate function, I don't see a better
>>>solution for mean function.
>>>
>>>
>>>     
>>>
>>The SQL aggregate function AVG() calculates the mean.  Just be sure to
>>coerce
>>integer values to float or decimal, if you want a non-integer mean of
>>integer data.
>>
>>select AVG(1.0*x)
>>from (
>>  select 1 as x
>>  union all
>>  select 2 as x
>>  union all
>>  select 5 as x
>>) T
>>
>>Steve Kass
>>Drew University
>>
>>   
>>
>>>Why dynamical SQL? there are thousands of the UDFs, and a simple joinning
>>>with the result of the UDF with other tables to get the final result.
>>>
>>>I know it's hard since I didn't post all the code. But the UDFs should have
>>>constant speed. And the dynamical SQL doesn't take much time when trying a
>>>single step.
>>>
>>>My question why a single step takes only half the time? comparing with the
>>>same step in a loop of thousands.
>>>
>>>
>>>
>>>"Mike C#" wrote:
>>>
>>>
>>>
>>>     
>>>
>>>>Based on nick's most recent admission, I'm suspecting a poorly written query
>>>>or lack of indexes inside the UDF.
>>>>
>>>>"Erland Sommarskog" <esq***@sommarskog.se> wrote in message
>>>>news:Xns97EC413B8EC3Yazorman@127.0.0.1...
>>>>  
>>>>
>>>>       
>>>>
>>>>>nick (n***@discussions.microsoft.com) writes:
>>>>>    
>>>>>
>>>>>         
>>>>>
>>>>>>I have table value UDFs. It takes about 2.5 minutes when I execute
>>>>>>select * from dbo.myudf('...')
>>>>>>
>>>>>>I have a stored procedure to run thousands of the UDFs as dynaml SQL:
>>>>>>
>>>>>>@sql = 'insert into @tablevalue select '+.....+' from
>>>>>>dbo.myudf('+...+'...)'
>>>>>>exec (@sql)
>>>>>>
>>>>>>However, it takes about 4.7 minutes to run the same query. Does the
>>>>>>dynamal sql cause the slowness? Or how much will checkpoint help? I
>>>>>>already set the database as simple Recovery model.
>>>>>>      
>>>>>>
>>>>>>           
>>>>>>
>>>>>I don't really see the point of inserting into a table variable in
>>>>>dynamic SQL...
>>>>>
>>>>>As the other folks, I would more suspect the INSERT than the dynamic
>>>>>SQL. When you run the function from the INSERT statement, it will
>>>>>execute in the context of a transaction. Depending on the isolation
>>>>>level, this could affect the execution time, particularly if there
>>>>>is blocking.
>>>>>
>>>>>You should alo run this several times to make sure. The difference
>>>>>could be due to natural variation because of the load on the server.
>>>>>
>>>>>--
>>>>>Erland Sommarskog, SQL Server MVP, esq***@sommarskog.se
>>>>>
>>>>>Books Online for SQL Server 2005 at
>>>>>http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
>>>>>Books Online for SQL Server 2000 at
>>>>>http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
>>>>>    
>>>>>
>>>>>         
>>>>>
>>>>  
>>>>
>>>>       
>>>>
Author
26 Jun 2006 3:19 PM
nick
Probably UDA is better in SQL 2005? However I am using V2000

Show quote
"Steve Kass" wrote:

> Nick,
>
> Here is an efficient way to find a median if you are using SQL Server 2005.
> This query gives the median [Freight] for each customer's orders:
>
> select
>   CustomerID,
>   avg(Freight) as medianFreight
> from (
>   select
>     CustomerID,
>     Freight,
>     row_number() over (partition by CustomerID order by Freight asc,
> OrderID asc) as r1,
>     row_number() over (partition by CustomerID order by Freight desc,
> OrderID desc) as r2
>   from Northwind..Orders
> ) T
> where r1 - r2 between -1 and 1
> group by CustomerID
> -- Idea from Itzik Ben-Gan's book T-SQL Querying
>
> -- SK
>
> nick wrote:
>
> >mean sometimes means average. What I've implemented is median....
> >
> >"Steve Kass" wrote:
> >
> > 
> >
> >>nick wrote:
> >>
> >>   
> >>
> >>>Ok, let me explain why dynamical SQL and let you know if the query is poor
> >>>written.
> >>>
> >>>The UDFs has one or two parameter and return a 20 some rows. The UDF will
> >>>calculate the meen value group by a category column. Since SQL Server don't
> >>>have aggregete function Mean(), I had to insert to data into a temp/table
> >>>variable. I tried write a stored procedure with temp table and create index.
> >>>it has the same performance as the UDF i wrote with table variable (Because
> >>>UDF doesn't allow temp table). In fact, I defined primary key in the table
> >>>varable for index to achieve the same performance.
> >>>
> >>>Unless using SQL 2005 with .Net aggregate function, I don't see a better
> >>>solution for mean function.
> >>>
> >>>
> >>>     
> >>>
> >>The SQL aggregate function AVG() calculates the mean.  Just be sure to
> >>coerce
> >>integer values to float or decimal, if you want a non-integer mean of
> >>integer data.
> >>
> >>select AVG(1.0*x)
> >>from (
> >>  select 1 as x
> >>  union all
> >>  select 2 as x
> >>  union all
> >>  select 5 as x
> >>) T
> >>
> >>Steve Kass
> >>Drew University
> >>
> >>   
> >>
> >>>Why dynamical SQL? there are thousands of the UDFs, and a simple joinning
> >>>with the result of the UDF with other tables to get the final result.
> >>>
> >>>I know it's hard since I didn't post all the code. But the UDFs should have
> >>>constant speed. And the dynamical SQL doesn't take much time when trying a
> >>>single step.
> >>>
> >>>My question why a single step takes only half the time? comparing with the
> >>>same step in a loop of thousands.
> >>>
> >>>
> >>>
> >>>"Mike C#" wrote:
> >>>
> >>>
> >>>
> >>>     
> >>>
> >>>>Based on nick's most recent admission, I'm suspecting a poorly written query
> >>>>or lack of indexes inside the UDF.
> >>>>
> >>>>"Erland Sommarskog" <esq***@sommarskog.se> wrote in message
> >>>>news:Xns97EC413B8EC3Yazorman@127.0.0.1...
> >>>>  
> >>>>
> >>>>       
> >>>>
> >>>>>nick (n***@discussions.microsoft.com) writes:
> >>>>>    
> >>>>>
> >>>>>         
> >>>>>
> >>>>>>I have table value UDFs. It takes about 2.5 minutes when I execute
> >>>>>>select * from dbo.myudf('...')
> >>>>>>
> >>>>>>I have a stored procedure to run thousands of the UDFs as dynaml SQL:
> >>>>>>
> >>>>>>@sql = 'insert into @tablevalue select '+.....+' from
> >>>>>>dbo.myudf('+...+'...)'
> >>>>>>exec (@sql)
> >>>>>>
> >>>>>>However, it takes about 4.7 minutes to run the same query. Does the
> >>>>>>dynamal sql cause the slowness? Or how much will checkpoint help? I
> >>>>>>already set the database as simple Recovery model.
> >>>>>>      
> >>>>>>
> >>>>>>           
> >>>>>>
> >>>>>I don't really see the point of inserting into a table variable in
> >>>>>dynamic SQL...
> >>>>>
> >>>>>As the other folks, I would more suspect the INSERT than the dynamic
> >>>>>SQL. When you run the function from the INSERT statement, it will
> >>>>>execute in the context of a transaction. Depending on the isolation
> >>>>>level, this could affect the execution time, particularly if there
> >>>>>is blocking.
> >>>>>
> >>>>>You should alo run this several times to make sure. The difference
> >>>>>could be due to natural variation because of the load on the server.
> >>>>>
> >>>>>--
> >>>>>Erland Sommarskog, SQL Server MVP, esq***@sommarskog.se
> >>>>>
> >>>>>Books Online for SQL Server 2005 at
> >>>>>http://www.microsoft.com/technet/prodtechnol/sql/2005/downloads/books.mspx
> >>>>>Books Online for SQL Server 2000 at
> >>>>>http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx
> >>>>>    
> >>>>>
> >>>>>         
> >>>>>
> >>>>  
> >>>>
> >>>>       
> >>>>
>

AddThis Social Bookmark Button