相关疑难解决方法(0)

如何优化查询

我有一个与此类似的数据库结构,

CREATE TABLE [dbo].[Dispatch](
    [DispatchId] [int] NOT NULL,
    [ContractId] [int] NOT NULL,
    [DispatchDescription] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Dispatch] PRIMARY KEY CLUSTERED 
(
    [DispatchId] ASC,
    [ContractId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[DispatchLink](
    [ContractLink1] [int] NOT NULL,
    [DispatchLink1] [int] NOT NULL,
    [ContractLink2] [int] NOT NULL,
    [DispatchLink2] [int] NOT NULL
) ON [PRIMARY]

GO
INSERT [dbo].[Dispatch] ([DispatchId], [ContractId], [DispatchDescription]) VALUES (1, 1, N'Test') …
Run Code Online (Sandbox Code Playgroud)

performance sql-server query-performance

9
推荐指数
1
解决办法
361
查看次数

为什么 [看似] 合适的索引不用于带有 OR 的 LEFT JOIN

我在 StackOverflow 数据库中有以下 [相当无意义,仅用于演示] 查询:

SELECT  *
FROM    Users u
        LEFT JOIN Comments c
            ON u.Id = c.UserId OR
               u.Id = c.PostId
WHERE   u.DisplayName = 'alex'
Run Code Online (Sandbox Code Playgroud)

Users表上唯一的索引是 ID 上的聚集索引。

Comments表具有以下非聚集索引以及 ID 上的聚集索引:

CREATE INDEX IX_UserID ON Comments
(
    UserID,
    PostID
)

CREATE INDEX IX_PostID ON Comments
(
    PostID,
    UserID
)
Run Code Online (Sandbox Code Playgroud)

查询的估计计划在这里

我可以看到优化器将做的第一件事是对用户表执行 CI 扫描以仅过滤那些用户 where DisplayName = Alex,有效地执行此操作:

SELECT  *
FROM    Users u
WHERE   u.DisplayName = 'alex'
ORDER BY Id
Run Code Online (Sandbox Code Playgroud)

并检索结果如下:

在此处输入图片说明

然后它会扫描评论 CI 并针对每一行,查看该行是否满足谓词 …

sql-server optimization execution-plan sql-server-2019 query-performance

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

在 INNER JOIN 内改进 OR

我有这个查询。这是第二个查询。第一个是在子查询之外使用左侧/或外部,查询计划很糟糕。(用完整的语法编辑了问题):

https://www.brentozar.com/pastetheplan/?id=HJEioh56N

nested loop (inner join)在查询计划中有 97%。

我确定问题出OR在第二个连接内部,因为我在这里和那里更改了一些东西,我可以摆脱它们,但我想确定处理此类数据的最佳方法是什么。所有这些表也有数百万行。

表定义:

CREATE TABLE [DBO].[TABLE1](
    [F1] [int] NOT NULL,
    [F1] [varchar](16) NOT NULL,
    [F3] [money] NOT NULL,
    [F4] [money] NOT NULL,
Run Code Online (Sandbox Code Playgroud)

我知道创建了这个索引:

在 DBO.TABLE1 ( F1, F2 ) 上创建非聚集索引 IX_TB1

该索引搜索现在是 14%,但HASH MATCH成本为 82%。

performance sql-server sql-server-2008-r2

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

使用“OR”运算符时的 SQL Server 索引扫描

我们实现了一个 Google 风格的搜索,其中在前端触发去抖动后运行 SQL 查询。(我们知道 SQL 可能是错误的技术,但我在这里陷入了启动混乱。)查询:

SELECT 
    TOP(50) [Name], [Surname]
FROM 
    [dbo].[Clients]
WHERE 
    [Name] LIKE @SearchTerm + '%' OR
    [Surname] LIKE @SearchTerm + '%'
Run Code Online (Sandbox Code Playgroud)

这是一个相当大的表,所以我在两列上添加了两个非聚集索引以帮助加快速度:

CREATE NONCLUSTERED INDEX [IX_Patients_Name] ON [dbo].[Clients]
(
    [Name] ASC
)
INCLUDE([Surname]);

CREATE NONCLUSTERED INDEX [IX_Patients_Surname] ON [dbo].[Clients]
(
    [Surname] ASC
)
INCLUDE([Name]);
Run Code Online (Sandbox Code Playgroud)

我的想法是 SQL 会在两列上进行索引查找,但查询优化器似乎决定使用索引扫描

聚集索引查找

对于这个简单的用例,这可能不是一个真正的问题,但我们有更复杂的版本,具有多个连接等。

有什么方法可以优化此查询以使用搜索吗?

sql-server optimization nonclustered-index

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

无法消除索引扫描

我有一个查询,即使使用SQL Sentry,也无法消除索引扫描。

这是查询:

SELECT TOP 30 codCliente FROM (
        SELECT t1.CodCliente, codcampo, valor, t1.chavealeat 
        FROM tblCliente AS t1 WITH(NOLOCK) 
            INNER JOIN tblClienteDetalhe AS t2 WITH(NOLOCK) 
            ON t1.codcliente = t2.codcliente 
            AND CodCampo IN(-1, 4)
        WHERE codStatus IN (0)  
            AND t1.ChavePeriodo < GETDATE()
            AND t1.CodStatusLigacao = 0
            AND EXISTS
            (
                SELECT codcliente FROM tblclientedetalhe WITH(NOLOCK) 
                WHERE codcampo = 3 AND valor = '2' 
                    AND codcliente = t1.codcliente
            )
            AND EXISTS
            (
                SELECT codcliente FROM tblclientedetalhe WITH(NOLOCK) 
                WHERE codcampo = 6
                    AND CONVERT(DATETIME, …
Run Code Online (Sandbox Code Playgroud)

performance sql-server-2008 sql-server clustered-index query-performance

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