我在一个表上有一个持久计算列,它只是由连接列组成,例如
CREATE TABLE dbo.T
(
ID INT IDENTITY(1, 1) NOT NULL CONSTRAINT PK_T_ID PRIMARY KEY,
A VARCHAR(20) NOT NULL,
B VARCHAR(20) NOT NULL,
C VARCHAR(20) NOT NULL,
D DATE NULL,
E VARCHAR(20) NULL,
Comp AS A + '-' + B + '-' + C PERSISTED NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
这Comp不是唯一的,并且 D 是每个组合的有效起始日期A, B, C,因此我使用以下查询来获取每个组合的结束日期A, B, C(基本上是 Comp 相同值的下一个开始日期):
SELECT t1.ID,
t1.Comp,
t1.D,
D2 = ( SELECT TOP 1 t2.D
FROM dbo.T t2
WHERE t2.Comp = …Run Code Online (Sandbox Code Playgroud) sql-server-2008 sql-server execution-plan computed-column bookmark-lookup
如何消除执行计划中的 Key Lookup (Clustered) 运算符?
表tblQuotes已经有一个聚集索引 (on QuoteID) 和 27 个非聚集索引,所以我不想再创建了。
我将聚集索引列QuoteID放在我的查询中,希望它会有所帮助 - 但不幸的是仍然相同。
或查看它:
这是 Key Lookup 运算符所说的:
询问:
declare
@EffDateFrom datetime ='2017-02-01',
@EffDateTo datetime ='2017-08-28'
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
IF OBJECT_ID('tempdb..#Data') IS NOT NULL
DROP TABLE #Data
CREATE TABLE #Data
(
QuoteID int NOT NULL, --clustered index
[EffectiveDate] [datetime] NULL, --not indexed
[Submitted] [int] NULL,
[Quoted] [int] NULL,
[Bound] [int] NULL,
[Exonerated] [int] NULL,
[ProducerLocationId] [int] …Run Code Online (Sandbox Code Playgroud) performance sql-server execution-plan sql-server-2012 bookmark-lookup query-performance
我试图理解为什么使用表变量会阻止优化器使用索引查找然后书签查找与索引扫描。
填充表:
CREATE TABLE dbo.Test
(
RowKey INT NOT NULL PRIMARY KEY,
SecondColumn CHAR(1) NOT NULL DEFAULT 'x',
ForeignKey INT NOT NULL
)
INSERT dbo.Test
(
RowKey,
ForeignKey
)
SELECT TOP 1000000
ROW_NUMBER() OVER (ORDER BY (SELECT 0)),
ABS(CHECKSUM(NEWID()) % 10)
FROM sys.all_objects s1
CROSS JOIN sys.all_objects s2
CREATE INDEX ix_Test_1 ON dbo.Test (ForeignKey)
Run Code Online (Sandbox Code Playgroud)
使用单个记录填充表变量,并尝试通过搜索外键列来查找主键和第二列:
DECLARE @Keys TABLE (RowKey INT NOT NULL)
INSERT @Keys (RowKey) VALUES (10)
SELECT
t.RowKey,
t.SecondColumn
FROM
dbo.Test t
INNER JOIN
@Keys k
ON
t.ForeignKey = …Run Code Online (Sandbox Code Playgroud) sql-server optimization sql-server-2008-r2 user-defined-table-type bookmark-lookup
我有一个如下表:
create table [Thing]
(
[Id] int constraint [PK_Thing_Id] primary key,
[Status] nvarchar(20),
[Timestamp] datetime2,
[Foo] nvarchar(100)
)
Run Code Online (Sandbox Code Playgroud)
Status在和字段上使用非聚集、非覆盖索引Timestamp:
create nonclustered index [IX_Status_Timestamp] on [Thing] ([Status], [Timestamp] desc)
Run Code Online (Sandbox Code Playgroud)
如果我查询这些行的“页面”,使用偏移/获取如下,
select * from [Thing]
where Status = 'Pending'
order by [Timestamp] desc
offset 2000 rows
fetch next 1000 rows only
Run Code Online (Sandbox Code Playgroud)
我知道该查询需要读取总共 3000 行才能找到我感兴趣的 1000 行。然后我希望它对这 1000 行中的每一行执行键查找以获取索引中未包含的字段。
但是,执行计划表明它正在对所有 3000 行进行键查找。我不明白为什么,当唯一的条件(按[状态]过滤和按[时间戳]排序)都在索引中时。
如果我用 cte 重新表述查询,如下所示,我或多或少会得到我期望第一个查询执行的操作:
with ids as
(
select Id from [Thing]
where Status = 'Pending'
order by [Timestamp] …Run Code Online (Sandbox Code Playgroud) 我正在使用 SQL 服务器,并且我一直在仔细研究关键查找的概念,
因此,如果您有一个键查找,您可以创建一个带有“包含”列的索引,以覆盖您在 select 语句中的非索引列。
例如,
SELECT ID, FirstName FROM OneIndex WHERE City = 'Las Vegas'
GO
Run Code Online (Sandbox Code Playgroud)
该索引将包括一个键查找,
CREATE NONCLUSTERED INDEX [IX_OneIndex_City] ON [dbo].[OneIndex]
(
[City] ASC
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
但是这个将删除密钥查找,
CREATE NONCLUSTERED INDEX [IX_OneIndex_Include] ON [dbo].[OneIndex]
(
City
) INCLUDE (FirstName,ID) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)
我的意思是这对性能有多大影响?键查找的运算符成本为 0.295969 (99%),但这究竟意味着什么?
你怎么知道你在那里需要第二个索引,什么时候会变成你试图添加太多索引而不值得的情况?
在我看来,有些查询可以包括索引扫描、键查找,而且似乎仍然执行得非常快。
非聚集索引是否固有地在表上存储对主键的引用,以便它可以根据需要进行键查找?...如果是这样,将主键指定为包含列的性能是否会降低或更高创建非聚集索引?
附带问题,为什么非聚集索引默认存储主键而不是聚集索引字段来对表进行键查找?...在主键不是聚集索引的情况下,是不是更慢为了进行键查找,而如果它存储了聚集索引,它可以以这种方式进行查找吗?
index sql-server nonclustered-index sql-server-2016 bookmark-lookup
非聚集索引使用聚集索引的键定位行与该表没有聚集索引且非聚集索引通过 RID 定位行之间是否存在性能差异?
不同级别的碎片是否也会影响这种性能比较?(例如,在这两种情况下,表的碎片率为 0%、50%、100%。)
performance sql-server clustered-index nonclustered-index bookmark-lookup performance-tuning