使用 JOIN 而不是 NOT IN 优化 SQL 查询

     2023-03-29     103

关键词:

【中文标题】使用 JOIN 而不是 NOT IN 优化 SQL 查询【英文标题】:Optimizing SQL query using JOIN instead of NOT IN 【发布时间】:2017-05-31 16:07:27 【问题描述】:

我有一个要优化的 sql 查询。我不是数据库的设计者,所以我无法更改结构、索引或存储过程。

我有一个包含发票(称为 faktura)的表,每张发票都有一个唯一的发票 ID。如果我们必须取消发票,则会在同一张表中创建第二张发票,但其中的字段(“modpartfakturaid”)引用原始发票 ID。

faktura 表示例:

invoice 1: Id=152549, modpartfakturaid=null

invoice 2: Id=152592, modpartfakturaid=152549

我们还有一个名为“BHLFORLINIE”的表,其中包含为客户提供的服务。部分服务已开具发票并与发票 (FAKTURA) 表中的记录相匹配。

我想做的是获取所有服务的列表,这些服务要么没有发票,要么没有已取消的发票。

我现在正在做的是:

`SELECT
    dbo.BHLFORLINIE.LeveringsDato AS treatmentDate,
    dbo.PatientView.Navn AS patientName,
    dbo.PatientView.CPRNR AS patientCPR
FROM
    dbo.BHLFORLINIE
INNER JOIN dbo.BHLFORLOEB 
    ON dbo.BHLFORLOEB.BhlForloebID = dbo.BHLFORLINIE.BhlForloebID
INNER JOIN dbo.PatientView 
    ON dbo.PatientView.PersonID = dbo.BHLFORLOEB.PersonID
INNER JOIN dbo.HENVISNING 
    ON dbo.HENVISNING.BhlForloebID = dbo.BHLFORLOEB.BhlForloebID
LEFT JOIN dbo.FAKTURA 
    ON dbo.BHLFORLINIE.FakturaId = FAKTURA.FakturaId
WHERE
    (dbo.BHLFORLINIE.LeveringsDato >= '2017-01-01' OR dbo.BHLFORLINIE.FakturaId IS NULL) AND
    dbo.BHLFORLINIE.ProduktNr IN (110,111,112,113,8050,4001,4002,4003,4004,4005,4006,4007,4008,4009,6001,6002,6003,6004,6005,6006,6007,6008,7001,7002,7003,7004,7005,7006,7007,7008) AND
    ((dbo.FAKTURA.FakturaType = 0 AND 
      dbo.FAKTURA.FakturaID NOT IN (
      SELECT FAKTURA.ModpartFakturaID FROM FAKTURA WHERE FAKTURA.ModpartFakturaID IS NOT NULL
      )) OR 
    dbo.FAKTURA.FakturaType IS NULL) 
 GROUP BY
    dbo.PatientView.CPRNR,
    dbo.PatientView.Navn,
    dbo.BHLFORLINIE.LeveringsDato`

有更聪明的方法吗?现在,由于“不在”子查询中,添加的查询执行速度慢了三倍。

非常感谢任何帮助!

彼得

【问题讨论】:

【参考方案1】:

您可以使用外连接并检查空值来查找不匹配项

SELECT customer.name, invoice.id 
FROM invoices i
INNER JOIN customer ON i.customerId = customer.customerId 
LEFT OUTER JOIN invoices i2 ON i.invoiceId = i2.cancelInvoiceId
WHERE i2.invoiceId IS NULL

【讨论】:

感谢您的快速回复!我想我可能举了一个非常糟糕的例子——对不起!我修改了我的原始问题以显示我正在执行的查询。发票表不是我要加入的表。

我啥时候应该使用 CROSS APPLY 而不是 INNER JOIN?

】我啥时候应该使用CROSSAPPLY而不是INNERJOIN?【英文标题】:WhenshouldIuseCROSSAPPLYoverINNERJOIN?我什么时候应该使用CROSSAPPLY而不是INNERJOIN?【发布时间】:2009-07-1617:42:21【问题描述】:使用CROSSAPPLY的主要目的是什么?我已经读到(模... 查看详情

MySQL join 是扫描表而不是使用索引

】MySQLjoin是扫描表而不是使用索引【英文标题】:MySQLjoinisscanningthetableratherthanusingtheindex【发布时间】:2020-09-1901:18:05【问题描述】:我有以下表格:显示创建表access_token_status;CREATETABLE`access_token_status`(`id`int(11)NOTNULLAUTO_INCREMENT,`s... 查看详情

在 PHP While 循环中使用 MySQL JOIN 而不是查询

】在PHPWhile循环中使用MySQLJOIN而不是查询【英文标题】:UseMySQLJOINinsteadofaqueryinPHPWhileloop【发布时间】:2013-02-0412:09:12【问题描述】:我正在尝试从PHPwhile循环中删除mysql查询并改用JOIN。我有一个问题SELECT*,SUM(CASEWHENposmonthlike\'2013%... 查看详情

何时更喜欢用 SelectMany() 表示的连接而不是用 Linq 中的 join 关键字表示的连接

...nLinq【发布时间】:2010-10-2616:46:18【问题描述】:Linq允许使用join关键字或使用带有where关键字的SelectMany()(即几个from关键 查看详情

在 JOIN 的 ON 子句中使用别名

】在JOIN的ON子句中使用别名【英文标题】:UsingAliasesintheONClauseofaJOIN【发布时间】:2015-02-1618:15:54【问题描述】:StackOverflow的新手(以及一般的编码)。我做了一些研究,但无法找到以下问题的答案:如何将两个表格连接到应用... 查看详情

GraphQL 如何做一个 JOIN 请求而不是许多顺序请求?

】GraphQL如何做一个JOIN请求而不是许多顺序请求?【英文标题】:GraphQLhowtodoaJOINrequestinsteadofmanysequentialrequest?【发布时间】:2018-11-0523:22:47【问题描述】:我有两种GraphQL类型:typeAuthorid:String!name:String!typeBookid:String!author:Author!name:... 查看详情

类型错误:voiceChannel.join 不是函数

...】:我一般是编码新手,所以期待nooby行为。我的DiscordBot使用命令node上线。我尝试了我的!ping命令,一切正常。但是,当我尝试使用声明的命令!play来播放来自YT的视频时,当我按下回车键时,机器人会因日志而崩溃 查看详情

Spring JPA/Hibernate Repository findAll 在 Kotlin 中默认执行 N+1 个请求而不是 JOIN

...Kotlin【发布时间】:2021-04-1817:20:15【问题描述】:我正在使用Kotlin处理SpringJPA/Hibernate应用 查看详情

如何使 OUTER JOIN 返回零而不是 NULL

】如何使OUTERJOIN返回零而不是NULL【英文标题】:HowtomakeanOUTERJOINreturnZEROinsteadofNULL【发布时间】:2017-10-2804:28:26【问题描述】:我正在尝试在SQLServer上完成此操作。最简单的数据表结构如下所示。Table:BlogBlogID,Title----------------1,Fir... 查看详情

Left Join 在 CMD Prompt 中工作,而不是 PHP

】LeftJoin在CMDPrompt中工作,而不是PHP【英文标题】:LeftJoinWorkinginCMDPrompt,notPHP【发布时间】:2012-04-1619:59:18【问题描述】:我有一个LEFTJOINSELECT语句,如下所示:SELECTsubmissions.subid,submissions.title,submissions.date,files.fileFROMsubmissionsLEFTJ... 查看详情

加入而不是相关子查询

...PRIMARYKEYnotnull,PostTitleNVARCHAR,BlogIDint,TotalCommentsint)是否可以使用任何Join而不是相关子查询来简化此查询?SELECTTOP5*FROMBlog 查看详情

Entity Framework Core:使用导航属性而不是连接

】EntityFrameworkCore:使用导航属性而不是连接【英文标题】:EntityFrameworkCore:usingnavigationpropertiesinsteadofjoins【发布时间】:2021-09-1516:19:12【问题描述】:最近我将NavigationProperties添加到没有任何FK的EFCore项目中,以便在尽可能多的... 查看详情

在 MYSQL 中执行 LEFT OUTER JOIN 时插入零而不是 NULL

】在MYSQL中执行LEFTOUTERJOIN时插入零而不是NULL【英文标题】:InsertingaZeroinsteadofNULLwhileperformingLEFTOUTERJOINinMYSQL【发布时间】:2012-10-2806:56:01【问题描述】:在对两个表执行LEFTOUTERJOIN时,有没有办法插入零而不是NULL?假设我有这样... 查看详情

当我使用 join each 时,查询执行期间资源超出

】当我使用joineach时,查询执行期间资源超出【英文标题】:ResourcesexceededduringqueryexecutionwhenIusejoineach【发布时间】:2013-04-1017:04:17【问题描述】:我尝试在Bigquery上运行一个联接查询,但我得到了“表太大而无法联接”的错误,... 查看详情

为啥在字符串连接上使用 os.path.join?

】为啥在字符串连接上使用os.path.join?【英文标题】:Whyuseos.path.joinoverstringconcatenation?为什么在字符串连接上使用os.path.join?【发布时间】:2012-12-0607:59:42【问题描述】:我认为我无法在这里看到更大的图景;但基本上我不知道... 查看详情

等待 pthread_create 完成而不使用 pthread_join

】等待pthread_create完成而不使用pthread_join【英文标题】:Waitingforpthread_createtofinishwithoutusingpthread_join【发布时间】:2009-04-0812:25:11【问题描述】:我想暂停一个线程,直到另一个线程完成初始化而不使用pthread_join。我尝试使用连... 查看详情

join,five,make哪个不是同类词?

...ive 参考技术Bfivefive是数词,jion,make是动词 参考技术Cfive不是同类词,因为他是一个数词,而join和make是动词。 参考技术DFive不是同类词。它是数词.make和join是动词 第5个回答 2020-07-19可以从词性来分析,第一个join是动词,第... 查看详情

linq学习——join

一、JOIN的作用   1、使用联接来结合两个或更多的集合的数据。   2、联接操作接受两个集合然后创建一个临时的对象集合,每一个对象包含原始集合对象中的所有字段。   Note:这里是包含而不... 查看详情