views:

48

answers:

4

If i have a view that generates multiple columns:

CREATE VIEW dbo.foo AS
SELECT 
    id,
    SUM(SELECT [...] ) AS c1,
    STDEV(SELECT [...] ) AS c2,
    AVG(SELECT [...] ) AS c3,
    MIN(SELECT [...] ) AS c4,
    MAX(SELECT [...] ) AS c5,
    SUM(SELECT [...] ) AS c6,
    [...]
    COUNT(SELECT [...] ) AS cN,
FROM Table
GROUP BY id

But i end up only asking for one of those calculated values:

SELECT id, c382
FROM foo
WHERE id = 42

Will SQL Server calculate all column values, only to ignore them?

In my experience, the answer seems to be "yes". A query:

SELECT id, c382
FROM foo
WHERE id = 42

will be slower than i think it should be. If i break the abstraction, duplicating the code i want:

SELECT id, c382
FROM (
      SELECT 
       id,
       MAX(SELECT [...] ) AS c382
   FROM Table
   GROUP BY id
) AS MiniView
WHERE id = 42

The query runs better.

Or perhaps it's in more real world constructs that it begins to fall apart:

SELECT bar.*, foo.384
FROM bar
    INNER JOIN foo
    ON bar.Bing = foo.id
WHERE bar.Reticulated = 'splines'

Am i crazy, or is SQL Server (2000) crazy?

+1  A: 

I don't understand the last part of your question, but the first part is a true statement and sums up the problem with views.

While views can help to make a db more understandable, it is rare they make it more performant exactly because of issues like this.

Best way to think of views is as macros for storing select statements. The place the view is referenced will be replaced by the contents of the view exactly.

Most of the time you can do much better with a stored procedure IMO.

Hogan
Can't join to a stored procedure
Ian Boyd
No you write a new stored proc that does only what you want to do. Or put the values from the proc into a temp table and join to that. Extensive use of views in a database is usually a BAD idea from a performance standpoint. Personally I only very rarely use a view. I'd rather see extensive triggers in a database than extensive views.
HLGEM
i'll have to check it again, but i think if you replace the join to a view with a join to a derives table: sql server will not execute unneeded stuffs.
Ian Boyd
+1  A: 

Yes, the view will calculate all your aggreagte columns, only to use the one you specified.

Unfortunately that is the way of views.

You could however refrein from creating so many columns in a view that would not be used?

astander
...or make a view for each of all possible combinations of those columns and use the one with the columns you need. (grin)
Hogan
@astander: The view is used to calculate additional information, which can be used during reporting and analysis.
Ian Boyd
@Hogan: The (n choose p) for all values all 1 <= p <= n gets into a pretty large number of views, and equally painful to find the right one.
Ian Boyd
Cab be used would not leed to will be used, or possible good performance... Nobody said to create 1..n columns. Create what you need, when you need it, then perfomance tune when required.
astander
@astander: You having a stroke or something over there? Need me to call a doctor or something?
Ian Boyd
I am sorry, am I missunderstanding your last comment?
astander
@Ian: The 1..n views comment was a joke...
Hogan
@astander: Perhaps. Try as i might, i cannot understand the line, "*Cab be used would not leed to will be used, or possible good performance...*" It reminded me of a little brochure i saw that talked about the warning signs of a stroke. On the front was the line, "*Ceilings make pie and markers drive the ocean with their feet.*". Or the other famous non-sentance, "*Has anyone really been far even as decided to use even go want to do look more like?*" i was trying to be funny.
Ian Boyd
That is typically the problem with **personal** jokes, not everyone gets where you are going. But thats fine X-)
astander
A: 

You could make a materialized view (one that is indexed and improve performance, but note that you can't do that on a view that calls a view (and if you think performance is bad now, wait until you try that).

Now for my cautionary tale about using views extensively in a database. We had some application developers who chose to use views, they never directly accessed a table only views. Design time was great, everything seemed wonderful and looked easy to maintain. Put the website live and loaded extensive customer data instead of small dataset they tested with, timeouts started on day one. As time went on, they changed more and more things as client requirements changed. Each time they did it through a view. Eventually views called views which called views, performance (already bad) plumeted. Finally they create a view that had so many views in it that it ran into the limit on the number of tables that can be referenced in a query (now mind these were all the same tables just all being referenced mulitple times in the views which called each other). Client got angry with poor performance that nobody seemed able to fix (After all it would involve a redesign from the ground up of every query in the application) and took the business elsewhere. This was the largest client that company had - not so good for developers who did the design.

HLGEM
Last time I checked, having aggregates in a materialized view wasn't possible. Has something changed?
Emtucifor
You are right, I wasn't thinking about that
HLGEM
+2  A: 

This is how it typically works in SQL Server 2000. This is also largely fixed in SQL Server 2005 and later.

RBarryYoung
Simple, succinct, and i assume true. i've not tested if it is fixed in 2005, but i trust you're right. +1 and accepted.
Ian Boyd