如何在SQL Server 2016中使用联接/联合将该查询转换为一个查询?

问题描述 投票:1回答:1

我的加入和工会技能充其量是最基本的。某些机构可以帮助我将以下查询更改为更有效的方法吗?

CREATE TABLE [dbo].[Doc2ChaptAssignment]
(
    [DocID_FK] [numeric](18, 0) NOT NULL,
    [mChapterID_FK] [numeric](18, 0) NOT NULL
)

CREATE TABLE [dbo].[Chapters]
(
    [mChapterID] [numeric](18, 0) NOT NULL,
    [Chapter Name] [varchar](128) NOT NULL
)

这里是查询

DECLARE @SearchTerm varchar(128) = 'Chapter One'

SELECT
    [mChapterID], [ChapterName]
FROM 
    [dbo].[ModuleChapters]
WHERE 
    [mChapterID] NOT IN (SELECT [mChapterID_FK]
                         FROM [dbo].[Doc2ChaptAssignment]
                         WHERE [DocID_FK] = @SearchTerm)
    AND [ChapterName] LIKE '%'+@1+'%'
ORDER BY 
    [ChapterName]
sql sql-server join union
1个回答
4
投票

他们写的方式是一种。通常使用NOT EXISTS

SELECT
   [mChapterID]
  ,[ChapterName]
FROM [dbo].[ModuleChapters]
WHERE [mChapterID] NOT EXISTS (SELECT 1
                           FROM [dbo].[Doc2ChaptAssignment]
                           WHERE [DocID_FK] = @SearchTerm
                           AND [mChapterID_FK] = [mChapterID])
AND [ChapterName] LIKE '%'+@1+'%'
ORDER BY [ChapterName]

通常较少,它被视为JOIN

SELECT
   [mChapterID]
  ,[ChapterName]
FROM [dbo].[ModuleChapters]
LEFT JOIN [dbo].[Doc2ChaptAssignment] on [mChapterID_FK] = [mChapterID]
WHERE [ChapterName] LIKE '%'+@1+'%' 
AND [mChapterID_FK] IS NULL
ORDER BY [ChapterName]

您可能不会立即看到性能提高,因为您的所有列都不是可空的。但是,如果这种情况发生变化,则NOT IN将必须做更多的[[work以获得相同的结果,因此NOT EXISTS将更快。就目前而言,我们需要查看执行计划和所有索引的DDL语句。查看有关getting help with a slow query.的博客。

请注意,您有一个non-SARGable predicate,这意味着该部分[ChapterName] LIKE '%'+@1+'%'不能使用索引查找。 Brent Ozar explains why this is slow,,但是它的不足之处是,如果您

可以

降低前导%,那么您[[可以可以看到性能提高。或者,甚至更好的是,如果您可以使用=操作数(您不是在搜索“喜欢”该术语的章节),并且具有覆盖索引,则可能会更快。
© www.soinside.com 2019 - 2024. All rights reserved.