I've been trying to understand why SQL server decides build a very complex query plan in some cases.
I've got two test Tables.
- Tab1 and Tabx
When the table only has a single data page the select statement behaves as I would expect and uses the Index efficiently.
![]()
However as soon as there's two data pages pages, the query run against xTab explodes into this:
![]()
I'm trying to understand why this is. Below are two test scripts that create the two tables:
CREATE TABLE dbo.Tab1
(
id BIGINT NOT NULL,
Alias VARCHAR(36) NOT NULL,
Version INT,
Locale VARCHAR(5),
Value1 VARCHAR(100) NOT NULL
);
CREATE NONCLUSTERED INDEX [IDX1] ON [dbo].[Tab1]
(
[id] ASC,
[Alias] ASC,
[Version] DESC,
[Locale] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Truncate table Tab1
Go
DECLARE @i AS int = 1;
WHILE @i < 200
BEGIN
SET @i = @i + 1;
INSERT INTO dbo.Tab1
(id, Alias, Version,Locale,Value1)
VALUES
(@i, 'x', 1,'en-us','Test1');
END;
Go
-- Take a look at how many pages we have
SELECT index_type_desc, page_count,record_count, avg_page_space_used_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(N'Test1'), OBJECT_ID(N'dbo.Tab1'), NULL, NULL , 'DETAILED');
Select
Id
From
Tab1 a
Where
a.id = 1
and a.Alias = 'x'
and (a.Locale = 'en-us' or a.Locale is NULL)
and a.Version = 1
Order By Version desc
vs
USE [test1]
GO
/****** Object: Table [dbo].[xTab1] Script Date: 09/05/2013 08:56:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[xTab1](
[ObjectPropertyCode] [bigint] IDENTITY(1,1) NOT NULL,
[ObjectCode] [bigint] NOT NULL,
[String200Name] [varchar](30) NOT NULL,
[String200] [varchar](2000) NOT NULL,
[GroupCode] [bigint] NOT NULL,
[Status] [char](1) NOT NULL,
[EntityObjectCode] [bigint] NOT NULL,
[Type] [varchar](5) NOT NULL,
[ObjectPropertyAlias] [varchar](60) NOT NULL,
[TypeObjectCode] [bigint] NOT NULL,
[Version] [int] NULL,
[Locale] [varchar](5) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[xTab1] ADD CONSTRAINT [DF_xTab1_StringName] DEFAULT ('') FOR [String200Name]
GO
ALTER TABLE [dbo].[xTab1] ADD CONSTRAINT [DF_xTab1_String] DEFAULT ('') FOR [String200]
GO
ALTER TABLE [dbo].[xTab1] ADD CONSTRAINT [DF__47jectPro__Group__08EA5793] DEFAULT ((0)) FOR [GroupCode]
GO
ALTER TABLE [dbo].[xTab1] ADD CONSTRAINT [DF_xTab1_Status] DEFAULT ('A') FOR [Status]
GO
ALTER TABLE [dbo].[xTab1] ADD CONSTRAINT [DF_xTab1_EntityObjectCode] DEFAULT ((-1)) FOR [EntityObjectCode]
GO
ALTER TABLE [dbo].[xTab1] ADD CONSTRAINT [DF_xTab1_47] DEFAULT ('') FOR [Type]
GO
ALTER TABLE [dbo].[xTab1] ADD CONSTRAINT [DF_xTab1_ObjectPropertyAlias] DEFAULT ('') FOR [ObjectPropertyAlias]
GO
ALTER TABLE [dbo].[xTab1] ADD CONSTRAINT [DF_xTab1_TypeObjectCode] DEFAULT ((-1)) FOR [TypeObjectCode]
GO
/****** Object: Index [IDX1] Script Date: 09/05/2013 08:51:45 ******/
CREATE NONCLUSTERED INDEX [IDX1] ON [dbo].[xTab1]
(
[ObjectCode] ASC,
[ObjectPropertyAlias] ASC,
[Version] DESC,
[Locale] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
Truncate table xTab1
Go
DECLARE @i AS int = 1;
WHILE @i < 101
BEGIN
SET @i = @i + 1;
INSERT INTO dbo.xTab1
(ObjectCode, ObjectPropertyAlias, Version,Locale,String200,GroupCode)
VALUES
(@i, 'x', 1,'en-us','Test1',0);
END;
Go
-- Take a look at how many pages we have
SELECT index_type_desc, page_count,record_count, avg_page_space_used_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(N'Test1'), OBJECT_ID(N'dbo.xTab1'), NULL, NULL , 'DETAILED');
Select
ObjectCode
From
xTab1 a
Where
a.ObjectCode = 514345440
and a.ObjectPropertyAlias = 'x'
and (a.Locale = 'en-us' or a.Locale is NULL)
and a.Version = 1
Order By Version desc