views:

1384

answers:

2

I am trying to create an index on the following view:

SELECT     'Candidate' AS Source, CandidateID AS SourceId, LastName + ', ' + FirstName AS SourceName
FROM         dbo.Candidates
UNION
SELECT     'Resource' AS Source, ResourceID AS SourceId, LastName + ', ' + FirstName AS SourceName
FROM         dbo.Resources
UNION
SELECT     'Deal' AS Source, DealID AS SourceId, CONVERT(varchar, Number) + '-' + CONVERT(varchar, RevisionNumber) AS SourceName
FROM         dbo.Deals
UNION
SELECT     'Job Order' AS Source, JobOrderID AS SourceId, CustomerNumber AS SourceName
FROM         dbo.JobOrders

I am getting the following error:

Msg 1939, Level 16, State 1, Line 2
Cannot create index on view '_Source' because the view is not schema bound.

I added WITH SCHEMABINDING to the CREATE and now get the following error:

Msg 10116, Level 16, State 1, Line 2
Cannot create index on view 'DEALMAKER.dbo._Source' because it contains one or more UNION, INTERSECT, or EXCEPT operators. Consider creating a separate indexed view for each query that is an input to the UNION, INTERSECT, or EXCEPT operators of the original view.

My questions are:

How would I create an index on this view? Would creating separate indexed views really work?

Lastly, am I really going to see a performance improvement for any queries that may JOIN this view?

Thanks in advance!

+3  A: 

You cannot create an index on a view that makes use of a union operator. Really no way around that, sorry!

I would imagine you've seen this, but check out this MSDN page. It gives the requirements for indexed views and explains what they are and how they work.

As to whether or not you'd see a performance benefit if you COULD index the view, that would depend entirely on the size of your tables. I would not expect any impact on creating separate indexed views, as I would assume that your tables are already indexed and you aren't doing any joining or logic in the view.

Adam Robinson
This is what I am afraid of ... any ideas how to work around this limitation?
mattruma
Are you seeing a huge slowdown in performance? Why do you feel you need to index the view?
Adam Robinson
To be honest ... I haven't tested the performance ... just looking ahead.
mattruma
I would be curious to see if it has a negative impact. Given that you just have straight table selects, I wouldn't think this view would do too much to your queries.
Adam Robinson
+4  A: 

Why in the WORLD are you using UNION?

With the literals in your SQL there is ZERO chance that you'll have duplicates. So again, why use UNION?

UNION forces a distinct to occur and there's little slower than DISTINCT.

But since you have something that looks like this:

SELECT 'A'
UNION
SELECT 'B'
UNION
SELECT 'C'

There's no possibility that you'll ever have duplicates.

Change it to UNION ALL and your query will perform much faster.

This is fundamental SQL - writing a well tuned query is more important than creating view indexes. Start with the basics, understand SQL, tune your query, THEN worry about spending space and slowing DML to improve query speed.

EDIT:

The literals in the query prevent dupes between tables. The only remaining possibility is dupes within a table(s). Since the columns look like PKs and there are no joins that could induce duplication and since the tables all look like lookup tables, what I said is correct. If that assumption isn't true than you may have a legitimate use of UNION without an ALL. However I find that 99% of the time people really meant to use ALL and it's a standard at our company to add a comment to SQL with only UNION because it's so often a mistake. i.e. UNION -- yes i need a distinct list.

You are a bit OTL on this. He is not using Select 'A', he is using Select 'A', othercols from Table so he will get as many rows in his result as ther are rows in Table. I would say that there is a good chance of duplicates
Jack Bolding
The point may be overstated, but I have to conditionally agree with the answer. Assuming CandidateID, ResourceID, etc. are PKs on those tables, and the name fields are 1-1 with the IDs, the SELECTs are probably already unique. UNION ALL is a good idea. Anything else may be premature optimization.
John M Gant
@jacco, you mean if joborderid isn't the PK of joborder table. Ok, that could be true. I'll correct.
Didn't know about UNION vs UNION ALL ... thanks! I'll give this a try!
mattruma