我使用任务的一个SQL Server 2000服务器上的SQL Server癞蛤蟆。

下面是我的查询:

SELECT CASE SLCE.GroupName WHEN 'Other' THEN ARM.FBCOMPANY 
                           WHEN 'Inter Co.' THEN ARM.FBCOMPANY 
                           ELSE SLCE.GroupName END AS [Company Name], 
       ARM.fcustno AS [Cust No], 
       ARM.fbcompany AS [Cust Name], 
       ARM.fcinvoice AS [Invoice No], 
       ARM.fdgldate AS [Post Date], 
       year(arm.fdgldate) AS [Year Posted], 
       CASE ARM.fcsource WHEN 'S' THEN 'Shipper' 
                         WHEN 'O' THEN 'Sales Order' 
                         WHEN 'R' THEN 'Receiver' 
                         WHEN 'C' THEN 'Customer' 
                         ELSE ARM.fcsource END AS [Source Doc Type], 
       CASE ARM.fcstatus WHEN 'N' THEN 'New' 
                         WHEN 'U' THEN 'Unpaid' 
                         WHEN 'P' THEN 'Partially Paid' 
                         WHEN 'F' THEN 'Paid in Full' 
                         WHEN 'H' THEN 'Held' 
                         WHEN 'V' THEN 'Voided' 
                         ELSE ARM.fcstatus END AS [Invoice Status], 
       ARM.fpono AS [Cust PO No], 
       ARM.fsalespn AS [Sales Person], 
       ARI.fitem AS [Item No], 
       ARI.fprodcl AS [Prod Class], 
       ARI.fshipkey AS [Qty Invoiced], 
       ARI.ftotprice AS [Net Invoiced], 
       ARI.fpartno AS [Part No], 
       ARI.frev AS [Part Rev], 
       cast(ARI.fmdescript AS VARCHAR(20)) AS [Part Description], 
       ARM.fsono AS [Sales No], 
       ARI.fsokey AS [SO Rels Key], 
       ARI.fordqty AS [Qty Ordered], 
       RED.[YEAR] AS [Year], 
       RED.PERIOD AS [RF Period] 
  FROM dbo.armast ARM 
       INNER JOIN dbo.aritem ARI 
          ON ARM.FCINVOICE = ARI.FCINVOICE 
       INNER JOIN slcdpm SLC 
          ON SLC.fcustno = ARM.fcustno 
       LEFT OUTER JOIN slcdpm_ext SLCE 
         ON SLC.identity_column = SLCE.fkey_id 
       INNER JOIN REDFRIDAYDATES..TBLREDFRIDAYALLDATES RED 
          ON RED.date = CAST (FLOOR (CAST (ARM.fdgldate AS FLOAT)) AS DATETIME) 
 WHERE ARM.fcstatus <> 'V' 
   AND RED.[YEAR] = year(getdate()) 
   AND ari.frev = 'REP' 
   AND ARI.fsalesacc IN ('4010001', '4010002', '4010003', '4010004', '4010005', '4010006', '4010007', '4010008', '4010009', '4010010', '4010018', '4010019', '4010020', '4010021', '4010031', '4010050', '4022000', '4031000', '4045000', '4055000', '4057000', '4060000', '4070000')

下面是TOAD的选项(使用差异突出显示)的是:

INNER JOIN dbo.aritem ARI 
          ON ARM.FCINVOICE = ***COALESCE (ARI.FCINVOICE , ARI.FCINVOICE)*** 
       INNER JOIN slcdpm SLC 
          ON SLC.fcustno = ARM.fcustno 
       LEFT OUTER JOIN slcdpm_ext SLCE 
         ON SLC.identity_column = SLCE.fkey_id 
       INNER JOIN REDFRIDAYDATES..TBLREDFRIDAYALLDATES RED 
          ON RED.date = CAST (FLOOR (CAST (ARM.fdgldate AS FLOAT)) AS DATETIME) 
 WHERE ARM.fcstatus <> 'V' 
   AND RED.[YEAR] = year(getdate()) 
   AND ari.frev = 'REP' 
   AND ARI.fsalesacc IN ('4010001', '4010002', '4010003', '4010004', '4010005', '4010006', '4010007', '4010008', '4010009', '4010010', '4010018', '4010019', '4010020', '4010021', '4010031', '4010050', '4022000', '4031000', '4045000', '4055000', '4057000', '4060000', '4070000') 
   ***AND ARI.[fpartno] >= CHAR(0)***

有人能告诉我为什么峰结合和附加和陈述加快超过50%这个查询?

有帮助吗?

解决方案

您已经采取了看看实际的执行计划。这些应该告诉你的SQL Server了在执行这些查询的不同方法。

其他提示

这绝对奇数之一。执行计划应该告诉你肯定的,但在数据库这样的性能变化几乎总是归结为一个指数。所以我最好的猜测是,不知何故的SQL Server缺少它可以使用一个索引,并加入使它更好地突出这些奇怪的变化。

但是,如果你正在寻找了解“为什么”参与,这样下一次你可以写你的查询是在第一时间更快,没什么好说的存在。

一个完整WAG:

我要猜测fpartno上有一个“非空”状态(因此所添加的滤波器总是通过),并且蟾蜍碰巧知道SQLServer是不足够聪明来检测> = CHAR(0)是总是如此。因此,这表明,蟾蜍正试图引导,在一个非常斜的方式,优化使用的东西,在它fpartno。这东西可能是在(fcinvoice,fpartno)综合指数..你有其中的一个?

和其他人一样说,解释计划应当在解释神秘证明是有益的。

无论这些变化对查询的逻辑意义任何效果(即,它们是“无OPS”)

这在ON子句COALESCE将阻止优化试图使用索引为ARI.FCINVOICE唯一物理效应。

同样地,在“> = CHAR(0)”可能对优化<唯一物理效应EM>可能是督促其考虑使用索引范围扫描(或者也可以是寻求)上一个索引有ARI。[fpartno]在它

所以,我的结论是,蟾蜍试图优化操作成使用了特定的索引,而无需实际的强制的它使用该索引有明确的提示。其实,这是因为与T-SQL优化器提示,真正的问题那种巧妙的是他们的依赖性和脆弱性。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top