Note that there are some explanatory texts on larger screens.

plurals
  1. POIndexed Views and Left Joins once and for all
    primarykey
    data
    text
    <p>I'm using MSSQL Server 2008 R2 and I'm trying to optimize my Views when I stumbled upon Indexed Views. Unfortunately most of my Views use a Left Outer Joins which is not supported with Indexed Views. After a bunch of research, I'm left confused the best way to go about this. The way I see it, I have the following options:</p> <p><strong>1)</strong> Convert the left joins to inner joins using the trick to simulate a left join with "OR (IsNull(a) AND IsNull(b))"</p> <p>I found this solution in a couple places, but there was mention of a performance loss.</p> <p><strong>2)</strong> Convert the left joins to inner joins and replace the nullable column's nulls with empty guids (00000000-0000-0000-0000-000000000000) and add a single row in the right table with a matching guid.</p> <p>This appears the most obvious performance-wise, but it seems a waste of space for every row that would otherwise be NULL.</p> <p><strong>3)</strong> Break my view up into two views. The first view being the majority of my logic that is Indexable. And the second view deriving from the first view and adding the left joins. </p> <p>The idea here being, there might be a performance gain via the base view being indexed. And that even querying the derived view would gain at least some of the performance benefit.</p> <p><strong>4)</strong> Don't index my views</p> <p>Would leaving the view the way it is be more performant than any of the above options?</p> <p><strong>5)</strong> The idea I didn't think of</p> <p>I scripted my basic scenario as follows:</p> <pre><code> CREATE TABLE [dbo].[tbl_Thumbnails]( [ThumbnailId] [uniqueidentifier] NOT NULL, [Data] [image] NULL, [Width] [smallint] NOT NULL, [Height] [smallint] NOT NULL CONSTRAINT [PK_tbl_Thumbnails] PRIMARY KEY CLUSTERED ( [ThumbnailId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO CREATE TABLE [dbo].[tbl_Tags]( [TagId] [uniqueidentifier] NOT NULL, [ThumbnailId] [uniqueidentifier] NULL CONSTRAINT [PK_tbl_Tags] PRIMARY KEY CLUSTERED ( [TagId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO CREATE VIEW [dbo].[v_Tags] WITH SCHEMABINDING AS SELECT dbo.tbl_Tags.TagId, dbo.tbl_Tags.ThumbnailId FROM dbo.tbl_Tags LEFT OUTER JOIN dbo.tbl_Thumbnails ON dbo.tbl_Tags.ThumbnailId = dbo.tbl_Thumbnails.ThumbnailId GO INSERT INTO tbl_Tags VALUES ('16b23bb8-bf17-4784-b80a-220da1163584', NULL) INSERT INTO tbl_Tags VALUES ('e8b50f03-65a9-4d1e-b3b4-268f01645c4e', 'a45e357b-ca9c-449a-aa27-834614eb3f6e') INSERT INTO tbl_Thumbnails VALUES ('a45e357b-ca9c-449a-aa27-834614eb3f6e', NULL, 150, 150) </code></pre> <p>Now, doing the following query yields "Cannot create index on view "Test.dbo.v_Tags" because it uses a LEFT, RIGHT, or FULL OUTER join, and no OUTER joins are allowed in indexed views. Consider using an INNER join instead.":</p> <pre><code>CREATE UNIQUE CLUSTERED INDEX [TagId] ON [dbo].[v_Tags] ( [TagId] ASC ) GO </code></pre> <p>This is expected behavior, but what course of action would you recommend to gets the best performance from my scenario? The take home point here is best performance.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload