什么';从SQL查询中排除可能结果的最有效方法是什么?

什么';从SQL查询中排除可能结果的最有效方法是什么?,sql,Sql,我有一个包含客户、订阅和发布表的订阅数据库 Subscriptions表包含所有订阅记录,每条记录都有三个标志来标记状态:isActive、isExpire和isPending。这些是布尔值,只有一个标志可以为真-这由应用程序处理 我需要确定所有没有续借他们之前订阅过的杂志的客户,我不确定我是否编写了最有效的SQL查询。如果我发现一个过期的订阅,我需要忽略它,如果他们已经有一个活动或等待订阅的特定杂志 以下是我所拥有的: SELECT DISTINCT Customers.id, Subscri

我有一个包含客户、订阅和发布表的订阅数据库

Subscriptions表包含所有订阅记录,每条记录都有三个标志来标记状态:isActive、isExpire和isPending。这些是布尔值,只有一个标志可以为真-这由应用程序处理

我需要确定所有没有续借他们之前订阅过的杂志的客户,我不确定我是否编写了最有效的SQL查询。如果我发现一个过期的订阅,我需要忽略它,如果他们已经有一个活动或等待订阅的特定杂志

以下是我所拥有的:

SELECT DISTINCT Customers.id, Subscriptions.publicationName
FROM Subscriptions
LEFT JOIN Customers
ON Subscriptions.id_Customer = Customers.id
LEFT JOIN Publications
ON Subscriptions.id_Publication = Publications.id
WHERE Subscriptions.isExpired = 1
AND NOT EXISTS
( SELECT * FROM Subscriptions s2
WHERE s2.id_Publication = Subscriptions.id_Publication
AND s2.id_Customer = Subscriptions.id_Customer
AND s2.isPending = 1 )
AND NOT EXISTS
( SELECT * FROM Subscriptions s3
WHERE s3.id_Publication = Subscriptions.id_Publication
AND s3.id_Customer = Subscriptions.id_Customer
AND s3.isActive = 1 )
我有超过50000条订阅记录,这个查询运行几乎需要一个小时,这告诉我存在大量的循环或其他情况,SQL引擎必须再次搜索每条记录以查找任何“isPending”和“isActive”记录


这是我的第一篇博文,如果我遗漏了问题中的任何信息,请保持温和:)谢谢。

我没有您完整的数据库结构,因此我无法测试以下查询,但它可能包含一些优化。我会让你们去测试,但会解释为什么我改变了,我改变了什么

select Distinct Customers.id, Subscriptions.publicationName 
from Subscriptions 
join Customers on Subscriptions.id_Customer = Customer.id
join Publications
ON Subscriptions.id_Publication = Publications.id
Where Subscriptions.isExpired = 1
And Not Exists
(select * from Subscriptions s2
join Customers on s2.id_Customer = Customer.id
join Publications
ON s2.id_Publication = Publications.id
where s2.id_Customer = s2.id_customer and 
(s2.isPending = 1 or s2.isActive = 1))
如果在Customer或Publications数据库中没有结果数据,那么订阅信息就没有用处,因此我取消了左连接,而选择了简单连接。组合这两个子查询。如果我记得的话,这些都是非常密集的,所以越少越好。上面我没有列出但可能值得研究的最后一件事是,您可以运行返回特定数据字段的子查询并在Exists子句中使用它吗?使用Select*将返回所有减慢处理速度的数据字段。不幸的是,我不确定你是否能限制你的结果,因为我没有一个可以测试的等效数据库(谷歌可能知道)

我怀疑可以对这个查询进行进一步的优化。删除Exists子句而使用in子句可能会有所帮助,但我现在想不出一种方法,看看如何匹配两个唯一字段(客户id和相关订阅)。让我知道这是否有帮助


对于一个有50k行的表,您应该能够在几秒钟内运行这样的查询。

它运行在什么硬件上?在您的数据库中,我假定订阅表中的每一行都是一个“订阅”的一个“续订”对吗?我的意思是,假设一个客户有一本杂志,子杂志将于2015年12月到期。当他续订订阅时,是在订阅表中创建一个新行,还是简单地将状态翻转回活动状态?Windows Server 2012 R2 Essentials 64位Intel Xeon CPU E3-1220 v3@3.10Ghz 4Gb RAMNate M。-是的,你是对的,我创建了一个新行,以便我们可以分析历史数据。如果我更改现有订阅的状态,那么我们将失去该功能。非常感谢。使用“OR”组合“isPending=1”和“isActive=1”取得了真正的改进。我感谢你的帮助:)很高兴能帮上忙!