Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 昂贵的左连接到空子查询?_Sql_Sql Server_Join_Subquery - Fatal编程技术网

Sql 昂贵的左连接到空子查询?

Sql 昂贵的左连接到空子查询?,sql,sql-server,join,subquery,Sql,Sql Server,Join,Subquery,这里的SQL新手试图更好地理解调度和高效的代码编写。我正在运行一个性能非常差的查询,我不明白为什么。我们正在使用SQL Server 2012 当我只运行子查询(别名为“te”)时,它运行不到一秒钟,返回零行(这是我所期望的)。但是当我运行完整的查询时,需要花费一分钟以上的时间。空集上的内部联接或左外部联接不总是返回空集吗?那么,当子查询不返回任何结果时,DB引擎不应该发现它不需要执行任何这些连接吗 有没有关于如何更好地优化的建议?将来编写SQL时,我应该记住哪些最佳实践 INSERT INTO

这里的SQL新手试图更好地理解调度和高效的代码编写。我正在运行一个性能非常差的查询,我不明白为什么。我们正在使用SQL Server 2012

当我只运行子查询(别名为“te”)时,它运行不到一秒钟,返回零行(这是我所期望的)。但是当我运行完整的查询时,需要花费一分钟以上的时间。空集上的内部联接或左外部联接不总是返回空集吗?那么,当子查询不返回任何结果时,DB引擎不应该发现它不需要执行任何这些连接吗

有没有关于如何更好地优化的建议?将来编写SQL时,我应该记住哪些最佳实践

INSERT INTO #target_events
   SELECT p.polyname,
          bp.PurposeAbbr,
          s.schid,
          s.ldate,
          es.EvStrId,
          es.evstrname,
          e.evparent,
          e.evid,
          e.Lat / 1000000.0 AS 'Lat',
          e.Lon / 1000000.0 AS 'Lon',
          e.eta,
          e.etd,
          e.PassOn,
          e.PassOnBoard,
          e.Activity,
          e.SchedStatus,
          e.EvClass
   FROM
   (
       SELECT te.*
       FROM #target_events te
            LEFT OUTER JOIN #target_events te2 ON te2.schid = te.schid
                                                  AND te2.EvStrId = te.EvStrId
                                                  AND te2.EvParent = te.EvParent
                                                  AND te2.Activity != te.Activity
       WHERE te.Activity IN(0, 1)
            AND te.SchedStatus = 3
            AND te2.EvId IS NULL
   ) te -- This subquery runs in under 1 second and returns zero rows
   INNER JOIN events e ON e.schid = te.schid
                          AND e.EvStrId = te.EvStrId
                          AND e.EvParent = te.EvParent
                          AND e.Activity != te.Activity
   INNER JOIN eventstrings es ON es.evstrid = e.evstrid
                                 AND es.schid = e.schid
   INNER JOIN schedules s ON s.schid = e.schid
   LEFT OUTER JOIN clients c ON c.clientid = e.clientid
   LEFT OUTER JOIN address a ON a.addrid = c.clientid
                                AND a.AddrType = 'CH' -- Client Home addresses.
   LEFT OUTER JOIN polygons p ON p.polyid = a.jurispolyid
   LEFT OUTER JOIN booking b ON b.bookingid = e.bookingid
   LEFT OUTER JOIN bookingpurpose bp ON bp.purposeid = b.purposeid; -- These joins take a long time...

只有当左表为空时,空集合上的左联接才为空。这是它的本质。当优化器构建一个执行计划时,它可能会以多种方式转换原始查询,包括更改连接的顺序。它无法确定查询的哪一部分此时将返回零行,因此在构建计划时无法考虑这一点。如果您需要解决性能问题,请学习阅读执行计划。这是b.purposeid索引吗?当您无法找出查询运行缓慢的原因时,您应该做的第一件事是查看执行计划。作为一个实验,尝试在te.*之前添加TOP 4000000000。它的行数比以往任何时候都多,TOP命令将强制SQL在尝试连接其他任何内容之前处理te和te2上的连接。由于临时文件的行估计可能有点冒险,所以这可能会神奇地欺骗SQL生成更好的计划。