目前我正在使用Union,这会导致]性能问题和运行时间较长的会话。我可以使用#temptable而不是Union吗?我已经编写了下面的查询,并使用了左连接。
SET NOCOUNT ON;
SELECT * FROM (
(SELECT DISTINCT si.num, si.code, 1 AS action_code
FROM stock si (NOLOCK)
LEFT OUTER JOIN product dpx (NOLOCK) ON si.owner_my_id = dpx.my_id
AND si.my_id = dpx.my_id
AND si.num = dpx.num
AND dpx.active_flag = 1
LEFT OUTER JOIN dp_page dpcx (NOLOCK) ON si.owner_my_id = dpcx.my_id
AND si.my_id = dpcx.my_id
AND si.num = dpcx.num
AND dpcx.active_flag = 1
LEFT OUTER JOIN dsi dsi (NOLOCK) ON si.owner_my_id = dsi.my_id
AND si.my_id = dsi.my_id
AND si.num = dsi.num
LEFT OUTER JOIN loadtable ilr (nolock)
ON si.my_id = ilr.my_id
AND si.num = ilr.num
AND getdate() between ilr.eff_date AND (end_date+1)
WHERE si.my_id = @my_id
AND si.owner_my_id = @my_id
AND (dpx.my_id IS NOT NULL OR dpcx.my_id IS NOT NULL OR dsi.my_id IS NOT NULL OR ilr.my_id IS NOT NULL) )
UNION
(SELECT DISTINCT dp.num, '-2' AS code, 0 AS action_code
FROM distributor_product dp (NOLOCK)
LEFT OUTER JOIN product dpx (NOLOCK) ON dp.my_id = dpx.my_id
AND dp.num = dpx.num
AND dpx.active_flag = 1
LEFT OUTER JOIN dp_page dpcx (NOLOCK) ON dp.my_id = dpcx.my_id
AND dp.num = dpcx.num
AND dpcx.active_flag = 1
LEFT OUTER JOIN dsi dsi (NOLOCK) ON dp.my_id = dsi.my_id
AND dp.num = dsi.num
LEFT OUTER JOIN loadtable ilr (nolock)
ON dp.my_id = ilr.my_id
AND dp.num = ilr.num
AND getdate() between ilr.eff_date AND (end_date+1)
WHERE dp.my_id = @my_id
AND (dpx.my_id IS NOT NULL OR dpcx.my_id IS NOT NULL OR dsi.my_id IS NOT NULL OR ilr.my_id IS NOT NULL)
) ) a
END
1条答案
按热度按时间n53p2ov01#
这是一个复杂的查询。一些优化肯定取决于您的各种表上的索引。你没跟我们说过这些。
这里有一些建议。
UNION ALL
代替UNION
。UNION
对结果集执行重复数据消除;对于较大的结果集,这可能非常耗时,因为重复数据消除需要进行数据洗牌和比较。它不会更改您的结果集。DISTINCT
。与UNION ALL
存在相同的性能问题。但从你的问题中还不清楚你是否可以停止使用DISTINCT
。NOLOCK
限定符。无论如何,它们可能帮不了太大的忙。SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
语句,而不是将NOLOCK隐藏在查询中。当您针对活动的事务性表执行历史报告时,有时会发生死锁。但请注意,NOLOCK语义可能会生成虚假结果,特别是在事务数据库中主动更改行的情况下。尽可能避免使用
LOCK
和READ UNCOMMITTED
。恕我直言,使用这些是草率的编程。如果这些建议对你没有帮助,请不要犹豫,再问一个问题。但如果你这样做,请..。
编辑可以使用内连接而不是左连接吗?
当您执行
rightT LEFT JOIN leftT ON rightT.something = leftT.something
时,您将从RIGRT获得所有行,即使是那些不符合ON条件的行。您的结果集包含缺少的Leftt列中的空值。但是,如果您执行
rightT INNER JOIN leftT ON rightT.something = leftT.something
,则不会从RIGRT获得行,除非它们匹配ON条件。INTERNAL JOIN取消不匹配的行。只有你才能回答关于为部分或全部查询的连接切换到内部连接的问题:你比‘toobz’(这就是我)上的某个rando更了解你的数据库设计。如果你仍然得到一个有用的结果集,其中包含被隐藏的不匹配的行,你可以切换。