sql server是否过滤了索引<> 0的表现与>不同0?

时间:2015-05-12 13:08:29

标签: sql-server filtered-index

我有一个带有Id列的表。

此列始终保持值> gt = = 0(没有约束来断言)。

我为value > 0过滤了此列的索引。

如果过滤器为value <> 0

,此索引的执行方式是否可能不同(更快/更慢的查询?)

也许一个是最佳实践,另一个是坏实践......

编辑,我写了这个剧本:

-- Structure
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tst20150513_Src]') AND type in (N'U'))
DROP TABLE [dbo].[tst20150513_Src]
GO

CREATE TABLE tst20150513_Src (
    ID INT NOT NULL
    , CONSTRAINT PK_tst20150513_Src PRIMARY KEY (ID)
)
GO


IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tst20150513_1]') AND type in (N'U'))
DROP TABLE [dbo].[tst20150513_1]
GO

CREATE TABLE tst20150513_1 (
    ID INT NOT NULL
    , CONSTRAINT PK_tst20150513_1 PRIMARY KEY (ID)
)
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tst20150513_2_1]') AND type in (N'U'))
DROP TABLE [dbo].[tst20150513_2_1]
GO

CREATE TABLE tst20150513_2_1 (
    ID INT NOT NULL
)
GO

CREATE NONCLUSTERED INDEX IDX_tst20150513_2_1 ON tst20150513_2_1 (ID)
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tst20150513_2_2]') AND type in (N'U'))
DROP TABLE [dbo].[tst20150513_2_2]
GO

CREATE TABLE tst20150513_2_2 (
    ID INT NOT NULL
)
GO

CREATE NONCLUSTERED INDEX IDX_tst20150513_2_2 ON tst20150513_2_2 (ID) WHERE ID <> 0
GO


IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tst20150513_2_3]') AND type in (N'U'))
DROP TABLE [dbo].[tst20150513_2_3]
GO

CREATE TABLE tst20150513_2_3 (
    ID INT NOT NULL
)
GO

CREATE NONCLUSTERED INDEX IDX_tst20150513_2_3 ON tst20150513_2_3 (ID) WHERE ID > 0
GO


IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tst20150513_2_4]') AND type in (N'U'))
DROP TABLE [dbo].[tst20150513_2_4]
GO

CREATE TABLE tst20150513_2_4 (
    ID INT NOT NULL
    , CONSTRAINT CHK_tst20150513_2_4 CHECK (ID <> 0)
)
GO

CREATE NONCLUSTERED INDEX IDX_tst20150513_2_4 ON tst20150513_2_4 (ID) WHERE ID <> 0
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tst20150513_2_5]') AND type in (N'U'))
DROP TABLE [dbo].[tst20150513_2_5]
GO

CREATE TABLE tst20150513_2_5 (
    ID INT NOT NULL
    , CONSTRAINT CHK_tst20150513_2_5 CHECK (ID > 0)
)
GO

CREATE NONCLUSTERED INDEX IDX_tst20150513_2_5 ON tst20150513_2_5 (ID) WHERE ID > 0
GO

-- Populate
; WITH CTE AS (
    SELECT
        ROW_NUMBER() OVER (ORDER BY [type], [number],[name]) AS n
    FROM master.dbo.spt_values AS T
)
INSERT tst20150513_Src ( ID )
SELECT
    n
FROM CTE WHERE n <= 1000

INSERT tst20150513_2_1 (ID)
SELECT ID FROM tst20150513_Src

INSERT tst20150513_2_2 (ID)
SELECT ID FROM tst20150513_Src

INSERT tst20150513_2_3 (ID)
SELECT ID FROM tst20150513_Src

INSERT tst20150513_2_4 (ID)
SELECT ID FROM tst20150513_Src

INSERT tst20150513_2_5 (ID)
SELECT ID FROM tst20150513_Src
GO

-- Tests
PRINT '
tst20150513_2_1
---------------
'

INSERT tst20150513_1 (ID)
SELECT ID FROM tst20150513_Src
GO

ALTER TABLE tst20150513_2_1 ADD
    CONSTRAINT FK_tst20150513_2_1 FOREIGN KEY (ID) REFERENCES tst20150513_1 (ID) ON DELETE CASCADE
GO

SET STATISTICS IO ON
GO

DELETE FROM tst20150513_1
GO

SET STATISTICS IO OFF
GO

IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tst20150513_2_1]') AND parent_object_id = OBJECT_ID(N'[dbo].[tst20150513_2_1]'))
ALTER TABLE [dbo].[tst20150513_2_1] DROP CONSTRAINT [FK_tst20150513_2_1]
GO

PRINT '
tst20150513_2_2
---------------
'

INSERT tst20150513_1 (ID)
SELECT ID FROM tst20150513_Src
GO

ALTER TABLE tst20150513_2_2 ADD
    CONSTRAINT FK_tst20150513_2_2 FOREIGN KEY (ID) REFERENCES tst20150513_1 (ID) ON DELETE CASCADE
GO

SET STATISTICS IO ON
GO

DELETE FROM tst20150513_1
GO

SET STATISTICS IO OFF
GO

IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tst20150513_2_2]') AND parent_object_id = OBJECT_ID(N'[dbo].[tst20150513_2_2]'))
ALTER TABLE [dbo].[tst20150513_2_2] DROP CONSTRAINT [FK_tst20150513_2_2]
GO

PRINT '
tst20150513_2_3
---------------
'

INSERT tst20150513_1 (ID)
SELECT ID FROM tst20150513_Src
GO

ALTER TABLE tst20150513_2_3 ADD
    CONSTRAINT FK_tst20150513_2_3 FOREIGN KEY (ID) REFERENCES tst20150513_1 (ID) ON DELETE CASCADE
GO

SET STATISTICS IO ON
GO

DELETE FROM tst20150513_1
GO

SET STATISTICS IO OFF
GO

IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tst20150513_2_3]') AND parent_object_id = OBJECT_ID(N'[dbo].[tst20150513_2_3]'))
ALTER TABLE [dbo].[tst20150513_2_3] DROP CONSTRAINT [FK_tst20150513_2_3]
GO

PRINT '
tst20150513_2_4
---------------
'

INSERT tst20150513_1 (ID)
SELECT ID FROM tst20150513_Src
GO

ALTER TABLE tst20150513_2_4 ADD
    CONSTRAINT FK_tst20150513_2_4 FOREIGN KEY (ID) REFERENCES tst20150513_1 (ID) ON DELETE CASCADE
GO

SET STATISTICS IO ON
GO

DELETE FROM tst20150513_1
GO

SET STATISTICS IO OFF
GO

IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tst20150513_2_4]') AND parent_object_id = OBJECT_ID(N'[dbo].[tst20150513_2_4]'))
ALTER TABLE [dbo].[tst20150513_2_4] DROP CONSTRAINT [FK_tst20150513_2_4]
GO

PRINT '
tst20150513_2_5
---------------
'

INSERT tst20150513_1 (ID)
SELECT ID FROM tst20150513_Src
GO

ALTER TABLE tst20150513_2_5 ADD
    CONSTRAINT FK_tst20150513_2_5 FOREIGN KEY (ID) REFERENCES tst20150513_1 (ID) ON DELETE CASCADE
GO

SET STATISTICS IO ON
GO

DELETE FROM tst20150513_1
GO

SET STATISTICS IO OFF
GO

IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tst20150513_2_5]') AND parent_object_id = OBJECT_ID(N'[dbo].[tst20150513_2_5]'))
ALTER TABLE [dbo].[tst20150513_2_5] DROP CONSTRAINT [FK_tst20150513_2_5]
GO

我对结果感到有些困惑:

tst20150513_2_1
---------------

(1000 row(s) affected)
Table 'tst20150513_2_1'. Scan count 1, logical reads 5006, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 2, logical reads 2018, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tst20150513_1'. Scan count 1, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1000 row(s) affected)

tst20150513_2_2
---------------

(1000 row(s) affected)
Table 'tst20150513_2_2'. Scan count 1, logical reads 3004, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 2, logical reads 2018, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tst20150513_1'. Scan count 1, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1000 row(s) affected)

tst20150513_2_3
---------------

(1000 row(s) affected)
Table 'tst20150513_2_3'. Scan count 1, logical reads 3004, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 2, logical reads 2018, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tst20150513_1'. Scan count 1, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1000 row(s) affected)

tst20150513_2_4
---------------

(1000 row(s) affected)
Table 'tst20150513_2_4'. Scan count 1, logical reads 5006, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 2, logical reads 2018, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tst20150513_1'. Scan count 1, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1000 row(s) affected)

tst20150513_2_5
---------------

(1000 row(s) affected)
Table 'tst20150513_2_5'. Scan count 1, logical reads 5006, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 2, logical reads 2018, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'tst20150513_1'. Scan count 1, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1000 row(s) affected)

tst20150513_2_1,tst20150513_2_4和tst20150513_2_5有5006个逻辑读取。 这些表的共同点是它们的索引要么不被过滤,要么&#34;结合&#34;完美地与&#34;关联&#34; CHECK条款。

我不知道为什么那些具有索引过滤但没有CHECK子句的其他2个表具有更多逻辑读取。

0 个答案:

没有答案