首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果源表中有许多行,带有子查询的SQL是否执行效率低下?

如果源表中有许多行,带有子查询的SQL是否执行效率低下?
EN

Stack Overflow用户
提问于 2016-11-16 07:33:39
回答 2查看 100关注 0票数 1

我正在查看一个应用程序,我发现这个SQL:

代码语言:javascript
复制
DELETE FROM Phrase
WHERE PhraseId NOT IN(SELECT Id FROM PhraseSource)

SQL的目的是从不位于PhraseSource表中的短语中删除行。

这两个表是相同的,具有以下结构

代码语言:javascript
复制
Id - GUID primary key
... 
... 
...
Modified int

...列大约有十个列,包含文本和数字数据。PhraseSource表可能包含也可能不包含修改后的列中数字较高的最近行以及不同的文本和数字数据。

有人能告诉我,这个查询会对短语表中的每一行执行SELECT Id PhraseSource吗?如果是这样的话,是否有一种更有效的方法来对其进行编码。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-16 07:39:57

在这种情况下,如果数据库系统不够聪明,可以为每一行计算子查询(但对于MS SQL Server,我认为它应该能够识别这样一个事实,即您不需要对子查询进行多次计算)。

还有一个更好的解决办法:

代码语言:javascript
复制
DELETE p 
FROM Phrase p
LEFT JOIN PhraseSource ps ON ps.Id = p.PhraseId
WHERE ps.Id IS NULL

这使用了与两个表的行相匹配的LEFT JOIN,但如果没有匹配,则会留下ps条目NULL。现在,您只需检查左侧的NULLs,以查看哪个Phrases没有匹配,并将删除它们。

所有类型的JOIN语句都是很好的在这个答案中描述

在这里你可以看到针对类似问题的三种不同方法在MySQL上进行了比较。正如@Drammy所提到的,要实际查看给定方法的性能,您可以在目标数据库上看到执行计划,并在相同问题的不同方法上进行性能测试。

票数 1
EN

Stack Overflow用户

发布于 2016-11-16 07:44:55

该查询应该优化为一个联接。你看过执行计划了吗?

如果您的性能不佳,很可能是因为guid主键。

默认情况下,主键是群集的。如果guid主键聚集在您的表上,这意味着表中的数据由主键排序。guids作为集群键的问题是,当您删除一条记录时,必须对表进行重新排序,并在磁盘上来回移动。

这篇文章对这个题目读得很好。

https://blog.codinghorror.com/primary-keys-ids-versus-guids/

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40626383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档