我正在运行SQL Server 2012并构建了一个查询,以减去一个主要的结果。我已经通过以下几种方式做到了这一点:
SELECT
campaignContact_id,
nlLogID,
emailAddress
FROM
sm_rel_campaign_contact rcc
WHERE
rcc.campaignContact_id NOT IN (SELECT campaignContact_id
FROM SM_BOUNCES)
AND rcc.campaigncontact_id NOT IN (SELECT campaignContact_id
FROM SM_DEFERRALS )
AND rcc.campaignContact_id NOT IN (SELECT campaignContact_id
FROM SM_FAILS)
AND rcc.campaignContact_id NOT IN (SELECT campaignContact_id
FROM SM_SENDS )
另一个是:
ALTER VIEW SM_QUEUE
AS
(
SELECT
campaignContact_id,
nlLogID,
emailAddress
FROM
sm_rel_campaign_contact rcc
WHERE
NOT EXISTS (SELECT * FROM SM_BOUNCES smb
WHERE rcc.campaignContact_id = smb.campaignContact_id)
AND NOT EXISTS (SELECT * FROM SM_DEFERRALS smd
WHERE rcc.campaignContact_id = smd.campaignContact_id)
AND NOT EXISTS (SELECT * FROM SM_FAILS smf
WHERE rcc.campaignContact_id = smf.campaignContact_id)
AND NOT EXISTS (SELECT * FROM SM_SENDS sms
WHERE rcc.campaignContact_id = sms.campaignContact_ID)
)
问题是在我创建视图后(无论哪种方式)运行此人:
SELECT count(*)
FROM SM_QUEUE
WHERE nlLogID = 81505
它的运行速度非常慢!我知道你可以索引视图,但我想知道是否有人有更好的建议? LEFT OUTER JOIN
可能是吗?
提前感谢任何反馈。
答案 0 :(得分:2)
您将无法为此视图编制索引 - 子查询或外部联接使其无法索引。
可能你在基表上缺少一些有用的索引。
的可能不同方法WITH Excludes
AS (SELECT campaignContact_id
FROM SM_BOUNCES
UNION ALL
SELECT campaignContact_id
FROM SM_DEFERRALS
UNION ALL
SELECT campaignContact_id
FROM SM_FAILS
UNION ALL
SELECT campaignContact_id
FROM SM_SENDS)
SELECT campaignContact_id,
nlLogID,
emailAddress
FROM sm_rel_campaign_contact rcc
WHERE NOT EXISTS (SELECT *
FROM Excludes e
WHERE e.campaignContact_id = rcc.campaignContact_id)
如果这样做无法帮助您编辑问题并包含CREATE TABLE
语句,包括所涉及表格的索引和详细信息。
答案 1 :(得分:0)
'not in'通常不能被优化(最终使用全表扫描),但查询分析器可以优化不存在。看看你是否可以在第一个查询中将not in更改为not exists。
答案 2 :(得分:0)
真的不能尝试,因为sql小提琴已关闭,我没有sql server直到星期一(也许你需要更多的括号):
WITH cte AS (
SELECT campaignContact_id FROM sm_rel_campaign_contact rcc
except
SELECT campaignContact_id FROM SM_BOUNCES
except
SELECT campaignContact_id FROM SM_DEFERRALS
except
SELECT campaignContact_id FROM SM_FAILS
except
SELECT campaignContact_id FROM SM_SENDS)
SELECT *
from cte
join sm_rel_campaign_contact rcc on rcc.campaignContact_id = cte.campaignContact_id
答案 3 :(得分:0)
我希望第二个版本(WHERE NOT EXISTS()
)比WHERE NOT IN ()
构造的版本运行得快一点。但是,这要求您在每个引用的表(campaignContact_id
,SM_BOUNCES
,SM_DEFERRALS
和SM_FAILS
)中的SM_SENDS
字段上都有索引。另外,既然你说这些是大表,那么你在nlLogID
字段上开始有索引吗?很可能您的查询花费了更多时间来扫描sm_rel_campaign_contact
表,而不是确定它是否在其他表中有相关数据;特别是因为你说问题中的两个版本都运行相同的'。
提示:尝试使用“显示执行计划”'运行查询。并解释那里发生了什么,或者只是截取屏幕截图并将其附加到上面的问题中,看看我们是否可以从中获得任何见解。