Showing posts with label adds. Show all posts
Showing posts with label adds. Show all posts

Friday, March 9, 2012

Function replacement for iterator table?

All:

One of the things that I didn't like about the iterator table that I have used for several years is that it adds a table to a schema that initially might look out of place. Over the past year I have been working at replacing the iterator table that I use as a utility with either an view that I could index or a function. I recently came accross this website when I was looking for something else:

http://stevekass.com/blog/page/2/

This function uses progressive set cross products within an inline function based on a CTE to generate a set cross product and then uses the ROW_NUMBER function to enumerate a set of integers. I tested this out and it seems really fast and this to me looks like a good candidate to replace my iterator table. Anyone else used this function as an iterator or something similar to it?

Dave

I forgot. I cannot use the function as use the function as part of an indexed view so I might want to stick with the table?|||

Yes, you cannot index a view that references such inline functions and you cannot index views that contains CTE in it's definition also.

Apart from this, there are other problems with the inline function approach. For example, the optimizer does not have real statistics on the number of rows so it makes a guess and this can cause serious performance problems depending on how you use the function. So you may want to compare this approach with the static table approach to see the pros and cons based on your workload. Other problems include higher compilation costs for the function (CPU usage) depending on the value of the parameters. The effect depends on whether your database server is constrained by CPU or disk or memory.

Below are some queries (only against the numbers table & tvf) that you could compare. Other cases are harder to generate because it depends on the use case.

set statistics io on

set statistics time on

go

select *

from dbo.tvf_Numbers(1, 1)

select *

from dbo.Numbers

where n = 1

declare @.n int

set @.n = 1

select *

from dbo.tvf_Numbers(1, 8000)

where n = @.n

select *

from dbo.Numbers

where n = @.n

select *

from dbo.tvf_Numbers(1, 255)

select *

from dbo.Numbers

where n between 1 and 255

go

set statistics io off

set statistics time off

go

I would simply stick with the table approach since it is easy to engineer and understand impact of it. The inline TVF approach cost is hidden due to the assumptions made and it is hard to comment when it will be beneficial or not (there are simply too many variables to consider).

|||

Thanks Umachandar,

That is exactly the kind of feedback that I was looking for. I appreciate the help.

Dave

Function replacement for iterator table?

All:

One of the things that I didn't like about the iterator table that I have used for several years is that it adds a table to a schema that initially might look out of place. Over the past year I have been working at replacing the iterator table that I use as a utility with either an view that I could index or a function. I recently came accross this website when I was looking for something else:

http://stevekass.com/blog/page/2/

This function uses progressive set cross products within an inline function based on a CTE to generate a set cross product and then uses the ROW_NUMBER function to enumerate a set of integers. I tested this out and it seems really fast and this to me looks like a good candidate to replace my iterator table. Anyone else used this function as an iterator or something similar to it?

Dave

I forgot. I cannot use the function as use the function as part of an indexed view so I might want to stick with the table?|||

Yes, you cannot index a view that references such inline functions and you cannot index views that contains CTE in it's definition also.

Apart from this, there are other problems with the inline function approach. For example, the optimizer does not have real statistics on the number of rows so it makes a guess and this can cause serious performance problems depending on how you use the function. So you may want to compare this approach with the static table approach to see the pros and cons based on your workload. Other problems include higher compilation costs for the function (CPU usage) depending on the value of the parameters. The effect depends on whether your database server is constrained by CPU or disk or memory.

Below are some queries (only against the numbers table & tvf) that you could compare. Other cases are harder to generate because it depends on the use case.

set statistics io on

set statistics time on

go

select *

from dbo.tvf_Numbers(1, 1)

select *

from dbo.Numbers

where n = 1

declare @.n int

set @.n = 1

select *

from dbo.tvf_Numbers(1, 8000)

where n = @.n

select *

from dbo.Numbers

where n = @.n

select *

from dbo.tvf_Numbers(1, 255)

select *

from dbo.Numbers

where n between 1 and 255

go

set statistics io off

set statistics time off

go

I would simply stick with the table approach since it is easy to engineer and understand impact of it. The inline TVF approach cost is hidden due to the assumptions made and it is hard to comment when it will be beneficial or not (there are simply too many variables to consider).

|||

Thanks Umachandar,

That is exactly the kind of feedback that I was looking for. I appreciate the help.

Dave

Function like SUM() but multiply

Is there a function that I can use to multiply all of the values of a column
from a result set together? Much like SUM() adds all the values together?
Or am I going to have to just use AVG() and COUNT() and multiply those 2
values together?
thnx,
Christoph
Christoph,
http://sqljunkies.com/WebLog/mosha/archive/2006/12/18/aggregate_multiplication.aspx
RLF
"Christoph Boget" <jcboget@.yahoo.com> wrote in message
news:O63$fDkwHHA.4132@.TK2MSFTNGP02.phx.gbl...
> Is there a function that I can use to multiply all of the values of a
> column from a result set together? Much like SUM() adds all the values
> together? Or am I going to have to just use AVG() and COUNT() and multiply
> those 2 values together?
> thnx,
> Christoph
>
|||On Mon, 9 Jul 2007 11:50:24 -0400, Christoph Boget wrote:

>Is there a function that I can use to multiply all of the values of a column
>from a result set together? Much like SUM() adds all the values together?
>Or am I going to have to just use AVG() and COUNT() and multiply those 2
>values together?
>thnx,
>Christoph
>
Hi Christoph,
If you're on SQL Server 2005, you can write a custom aggregate for this.
However, the technique below, which works on all versions of SQL Server,
is probably faster (though not really easy to understand for the novice
coder, and requiring some maths skills to graps as well).
(Simple version - use only if you know for sure that all values are > 0)
SELECT Grp, POWER(10.0, SUM(LOG10(Value))) AS Product
FROM YourTable
GROUP BY Grp;
(Advanced version - handles 0 and <0 values gracefully)
SELECT Grp,
CASE
WHEN MAX(CASE WHEN Value = 0 THEN 1 END) = 1 THEN 0
ELSE CASE
WHEN COUNT(CASE WHEN val < 0 THEN 1 END) % 2 = 0
THEN 1 ELSE -1
END * POWER(10.0, SUM(LOG10(NULLIF(ABS(Value),0))))
END AS Product
FROM YourTable
GROUP BY Grp;
(Advanced version, written in an even more incomprehensible way but
maybe a bit faster)
SELECT Grp,
CAST(ROUND(EXP(SUM(LOG(ABS(NULLIF(Value,0)))))*(1-SUM(1-SIGN(Value))%4)*(1-SUM(1-SQUARE(SIGN(val)))),0)
AS INT) AS Product
FROM YourTable
GROUP BY Grp;
These techniques are all described and explained in Itzik Ben-Gan's book
"Inside Microsoft SQL Server 2005 T-SQL Querying", page 358-360.
Hugo Kornelis, SQL Server MVP
My SQL Server blog: http://sqlblog.com/blogs/hugo_kornelis