【问题标题】:How to optimize the left outer join with the case statement?如何用case语句优化左外连接?
【发布时间】:2020-02-04 15:35:46
【问题描述】:

我有两个名为 genproductstoreindex 和 QAT_ListElid2 的表。我已经加入了左外连接,但是执行需要很长时间。

SELECT genproductstoreindex.[ElID]
    ,CASE 
        WHEN QAT_ListElid2.LeftTSMKEY IS NULL
            THEN genproductstoreindex.[TSMKEY]
        ELSE QAT_ListElid2.LeftTSMKEY + RightTSMKEY
        END
    ,[Numerical]
    ,[StringField]
    ,[DateField]
    ,[TableLevel]
    ,[TsmPath]
FROM genproductstoreindex
LEFT OUTER JOIN QAT_ListElid2 ON genproductstoreindex.ListElid = QAT_ListElid2.ListElid

为了使用 case case 语句优化左外连接,我已替换为以下代码,但数据看起来不正确。请帮我解决这个问题。

DECLARE @lefttsmkey NVARCHAR(30)

SET @lefttsmkey = NULL

IF @lefttsmkey IS NULL
BEGIN
    SELECT genproductstoreindex.[ElID]
        ,genproductstoreindex.[TSMKEY]
        ,[Numerical]
        ,[StringField]
        ,[DateField]
        ,[TableLevel]
        ,[TsmPath]
    FROM genproductstoreindex
    LEFT OUTER JOIN QAT_ListElid2 ON genproductstoreindex.ListElid = QAT_ListElid2.ListElid
END
ELSE
BEGIN
    SELECT genproductstoreindex.[ElID]
        ,QAT_ListElid2.LeftTSMKEY + RightTSMKEY AS [TSMKEY]
        ,[Numerical]
        ,[StringField]
        ,[DateField]
        ,[TableLevel]
        ,[TsmPath]
    FROM genproductstoreindex
    LEFT OUTER JOIN QAT_ListElid2 ON genproductstoreindex.ListElid = QAT_ListElid2.ListElid
END

【问题讨论】:

  • 如果您能提供创建表和插入脚本会很有帮助。
  • 在你的第一个查询中使用 where 条件-> where QAT_ListElid2.LeftTSMKEY IS NULL。
  • 哪一列属于哪个表?

标签: sql sql-server optimization left-join case


【解决方案1】:

第一个查询看起来不错。您希望这些索引能够快速运行:

create index idx1 on genproductstoreindex(listelid);
create index idx2 on indexqat_listelid2(listelid, lefttsmkey);

如果RightTSMKEYindexqat_listelid2 中的一列,则将其添加到第二个索引中。

您可以通过将查询中使用的所有列添加到相关索引来覆盖这两个索引。这将使它们更有可能被使用。 (如果您发现 DBMS 不使用其中一个,无论如何您都可以轻松地再次删除它。)

【讨论】:

  • 谢谢。我们可以优化左外连接吗
  • 没有。左外连接正是您想要的,或者我理解它。您想显示所有genproductstoreindex 并在可用的情况下加入QAT_ListElid2。你正在这样做。查询很好,所以你所能做的就是1)提供索引,2)投资硬件,3)限制你选择的数据。现在您正在选择所有genproductstoreindex。问问自己:这真的有必要吗?仅从表中选择某些数据还不够吗?如果您需要这一切,那么我不会在您的查询中更改任何内容。
  • 感谢您的精彩解释。根据您的理解,它是正确的。我想从 genproductstoreindex 获取所有数据。只是我需要处理评论。
【解决方案2】:
SELECT genproductstoreindex.[ElID]
    ,genproductstoreindex.[TSMKEY]
    ,[Numerical]
    ,[StringField]
    ,[DateField]
    ,[TableLevel]
    ,[TsmPath]
FROM genproductstoreindex with (nolock)
LEFT OUTER JOIN QAT_ListElid2 with (nolock) ON genproductstoreindex.ListElid = QAT_ListElid2.ListElid
where QAT_ListElid2.LeftTSMKEY IS NULL
UNION
SELECT genproductstoreindex.[ElID]
    ,QAT_ListElid2.LeftTSMKEY + RightTSMKEY AS [TSMKEY]
    ,[Numerical]
    ,[StringField]
    ,[DateField]
    ,[TableLevel]
    ,[TsmPath]
FROM genproductstoreindex with (nolock)
LEFT OUTER JOIN QAT_ListElid2 with (nolock) ON genproductstoreindex.ListElid = QAT_ListElid2.ListElid
where QAT_ListElid2.LeftTSMKEY IS NOT NULL

【讨论】:

  • 你应该总是描述你的解决方案是如何解决 OP 问题的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多