Sql server 是否有sql server筛选索引<&燃气轮机;0的性能与>;0?
我有一个Id列的表 此列始终保持值>=0(不存在断言此值的约束) 我在该列上有一个索引,已筛选为Sql server 是否有sql server筛选索引<&燃气轮机;0的性能与>;0?,sql-server,filtered-index,Sql Server,Filtered Index,我有一个Id列的表 此列始终保持值>=0(不存在断言此值的约束) 我在该列上有一个索引,已筛选为value>0 如果筛选器为值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].[tst20150
value>0
如果筛选器为值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、tst20150513_2_4和tst20150513_2_5有5006个逻辑读取。
这些表的共同点是,它们的索引要么未被过滤,要么与“关联的”CHECK
子句完美地“组合”
我不明白为什么那些具有索引过滤器的表比其他两个表具有更多的逻辑读取,但是没有
CHECK
子句。据我所知,fileterd index可以快速提取您需要的数据。所以我认为你必须回答你想要提取什么样的数据。我真的不明白你想提取什么数据。当然,您可以有几个相互覆盖的提取。在这种情况下,您可以考虑创建多个索引-这取决于数据的大小和类型(它将被读取或插入和更新)以及可以为附加索引牺牲的空间。我需要检索具有ID 0的行,但是由于ID值总是(非严格的)正,我现在写了“创建非聚集……ID 0”。。您应该只看到Id列包含范围为>0
的筛选索引的负值时性能下降。如果不支持负值,即在您的情况下,则无需指定0
的范围。话虽如此,对于您的示例,我建议将Id列设置为主键
,但如果您无法使用非聚集索引hh,@Geewers,从这个角度来看,我同意您的论点。但如果他没有负值,他可以将文件索引
更改为0
。当然,他必须确保负值不会意外出现。@Bogdanov:的确,他可以:-),如果查询碰巧使用0,则其特定场景的性能也会受到影响。
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)