2009-08-28 22 views
1

SQL Server 2000 Server上でQuestのTOADを使用しています。ここでクエリの最適化 - なぜこれがクエリのスピードアップですか?

は私のクエリです:ここでは

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') 

はヒキガエルのオプションは(違いが強調されて)である:それが合体し、追加と文は、このクエリをスピードアップする理由

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%以上?

答えて

3

実際の実行計画を見てきましたか。これらは、SQL Serverがこれらのクエリを実行する際に取ったさまざまなアプローチを示します。

1

間違いなく間違いです。実行計画は確かに教えてくれるはずですが、データベースのこのようなパフォーマンスの変化はほとんどの場合インデックスになります。だから、私の最高の推測は、何とかSQL Serverにインデックスを紛失していて、これらの変わった変更を追加すると、それがより優れているということです。

しかし、あなたが「なぜ」ということを学び、次回はより速くなるようにクエリを書くことができるようになったら、本当に何もありません。

1

完全WAG:私はfpartnoはその上に「nullでない」状態を(ので、追加のフィルタが常に通る)があること、およびヒキガエルはそのSQLServerのを知って起こることを推測するつもりです

は十分にスマートではありません> = CHAR(0)が常に真であることを検出します。これは、Toadが非常に斜めの方法で、オプティマイザにfpartnoを持つものを使用するように誘導しようとしていることを示しています。その何かが(fcinvoice、fpartno)の複合インデックスになる可能性があります。あなたはそれらの1つを持っていますか?

他の人が言ったように、説明計画は謎を説明するのに役立つはずです。

1

これらの変更のどちらが(つまり、彼らは「何のOPS」ではない)、クエリの論理的な意味上の任意の効果を持っている

ON句にCOALESCEからオプテ​​ィマイザを防ぐためになることだけ物理的効果ARI.FCINVOICEの索引を使用しようとしています。同様に

、「> = CHAR(0)」持っていたインデックスに(またはも求める)インデックス付きのレンジ・スキャンを使用することを検討することをprodにあるかもしれないオプティマイザに持つことができる唯一の物理的効果ARI。それで[fpartno]。

私の結論は、TOADが特定のインデックスを実際に使用せずにオプティマイザを操作しようとしていることです。明示的なHINTでそのインデックスを使用するように強制します。実際、T-SQLオプティマイザのヒントの実際の問題は、依存関係や脆弱性の問題であるため、賢明です。