慢左双加入

时间:2015-03-30 09:41:42

标签: sql sql-server left-join

我有以下查询在3个表之间执行左连接。问题是运行需要20秒,即使只返回几行。如果我从商品表中省略“大字段”,则查询几乎立即执行。所以看起来问题是由于某种原因,sqlserver在应用where语句之前获取这些字段的值。有没有办法让这个查询执行得更快?

SELECT N0."OID"
    ,N1."FirstName"
    ,N1."LastName"
    ,N0."SmallField"
    ,N0."LargeField1"
    ,N0."LargeField2"
FROM (
    (
        "dbo"."Offer" N0 LEFT JOIN "dbo"."Address" N1 ON (N0."OfferDeliveryAddress" = N1."OID")
        ) LEFT JOIN "dbo"."Customer" N2 ON (N0."Customer" = N2."OID")
    )
WHERE (
        N0."GCRecord" IS NULL
        AND (
            (isnull(CharIndex('John Smith', N2."FirstName" + ' ' + N2."LastName"), 0) > 0)
            OR (isnull(CharIndex('John Smith', N2."LastName" + ' ' + N2."FirstName"), 0) > 0)
            OR (isnull(CharIndex('John Smith', N2."FirstName"), 0) > 0)
            OR (isnull(CharIndex('John Smith', N2."LastName"), 0) > 0)
            )
        )

3 个答案:

答案 0 :(得分:1)

至少你可以优化你的位置条件如下:

WHERE (
        N0."GCRecord" IS NULL
        AND (
            (isnull(CharIndex('John Smith', N2."FirstName" + ' ' + N2."LastName"), 0) > 0)
            OR (isnull(CharIndex('John Smith', N2."LastName" + ' ' + N2."FirstName"), 0) > 0)
            )
        )

因为最后两个条件包含在前两个条件中。

<强>被修改 作为一个例子,看看为什么这是真的:

FirstName = 'XXXJohn Smith'
LastName = 'YYY'

FirstName + ' ' + LastName = 'XXXJohnSmith YYY' 

所以,如果 JohnSmith 包含在FirstName中,它也包含在FirstName + ' ' + LastName

答案 1 :(得分:1)

将您的WHERE子句更改为sargable子句:

WHERE (
        N0."GCRecord" IS NULL
        AND (
               (N2."FirstName" LIKE 'John%' AND N2."LastName" LIKE 'Smith%') OR 
               (N2."LastName" LIKE 'John%' AND N2."FirstName" LIKE 'Smith%') OR 
                N2."FirstName" LIKE 'John Smith%' OR 
                N2."LastName" LIKE 'John Smith%' 
            )
        )

将索引添加到列FirstNameLastName。 这个where子句应该从这些索引中受益,因为LIKE 'ABC%'是可以攻击的。

答案 2 :(得分:0)

  • 首先在选择部分中删除N0。&#34; LargeField1&#34;,N。&#34; LargeField2&#34;有所作为吗?

  • 第二部分,N2部分。&#34; FirstName&#34;和N2。&#34;姓氏&#34;可能有问题,因为查询函数没有使用数据库索引

  • 请检查您的执行计划。