标签: bookmark-lookup

持久计算列上的索引需要键查找以获取计算表达式中的列

我在一个表上有一个持久计算列,它只是由连接列组成,例如

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

24
推荐指数
2
解决办法
3228
查看次数

消除会降低性能的键查找(集群)运算符

如何消除执行计划中的 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

24
推荐指数
2
解决办法
3万
查看次数

为什么表变量强制索引扫描而临时表使用查找和书签查找?

我试图理解为什么使用表变量会阻止优化器使用索引查找然后书签查找与索引扫描。

填充表:

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

18
推荐指数
1
解决办法
5089
查看次数

为什么我看到的是所有读取行的键查找,而不是所有与 where 子句匹配的行?

我有一个如下表:

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-server nonclustered-index bookmark-lookup pagination

14
推荐指数
1
解决办法
765
查看次数

减少键查找

我正在使用 SQL 服务器,并且我一直在仔细研究关键查找的概念,

http://blog.sqlauthority.com/2009/10/07/sql-server-query-optimization-remove-bookmark-lookup-remove-rid-lookup-remove-key-lookup/

因此,如果您有一个键查找,您可以创建一个带有“包含”列的索引,以覆盖您在 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%),但这究竟意味着什么?

你怎么知道你在那里需要第二个索引,什么时候会变成你试图添加太多索引而不值得的情况?

在我看来,有些查询可以包括索引扫描、键查找,而且似乎仍然执行得非常快。

performance sql-server-2008 sql-server bookmark-lookup

6
推荐指数
2
解决办法
9746
查看次数

将主键指定为非聚集索引中的包含列有什么区别吗?

非聚集索引是否固有地在表上存储对主键的引用,以便它可以根据需要进行键查找?...如果是这样,将主键指定为包含列的性能是否会降低或更高创建非聚集索引?

附带问题,为什么非聚集索引默认存储主键而不是聚集索引字段来对表进行键查找?...在​​主键不是聚集索引的情况下,是不是更慢为了进行键查找,而如果它存储了聚集索引,它可以以这种方式进行查找吗?

index sql-server nonclustered-index sql-server-2016 bookmark-lookup

5
推荐指数
1
解决办法
289
查看次数

RID 查找与密钥查找之间的性能差异?

非聚集索引使用聚集索引的键定位行与该表没有聚集索引且非聚集索引通过 RID 定位行之间是否存在性能差异?

不同级别的碎片是否也会影响这种性能比较?(例如,在这两种情况下,表的碎片率为 0%、50%、100%。)

performance sql-server clustered-index nonclustered-index bookmark-lookup performance-tuning

2
推荐指数
1
解决办法
4698
查看次数