2

私は非常に単純なクエリを持っていますが、それは私を完全に狂わせています。

状況は次のとおりです。

  • 2 つのデータベース サーバーがあります。
  • 1 つは古い SQL Server 2000 (VM) で、リソースは非常に最小限です。
  • もう 1 つは非常に大規模な SQL Server 2005 エンタープライズ クラスタで、非常に膨大な量のリソースが利用可能です。
  • 3 秒で実行され、SQL Server 2000 で 50,000 行以上のデータを返す大きなクエリのごく一部があります。
  • この同じ小さなクエリは、SQL Server 2005 で 1000 行を返すのに 15 分以上かかります
  • 私が使用しているデータベースは、これら 2 つのサーバーのミラー イメージです。同じテーブル、テーブル内の同じデータ、テーブルの同じインデックスなど。

SQL Server 2005 テーブルにさまざまなインデックスを作成し、存在するすべてのインデックスをデフラグし、テーブル統計を更新してみました。SQL Server 2005 でこのクエリを高速に実行することはできませんでした。現在、SQL に対して他に何も実行していません。 Server 2005 サーバー、および私たちの DBA は、構成の問題ではなく、SQL Server 2000 と SQL Server 2005 の間の機能の廃止とは関係がないことを保証します.

クエリは次のとおりです。

SELECT (CASE 
             WHEN TeamMember.ID IN  (SELECT DISTINCT ProjMgrID FROM ProjMgr)
                THEN 'Yes' 
                ELSE 'No' 
        END) AS OnProjAsMgr 
FROM TeamMember

したがって、すべての ProjMgr の個別のリストを返し、TeamMember がそのリストにある場合は、OnProjAsMgr 値に「Yes」を割り当てます。

私はまったくの SQL 初心者で、これは前任者によって書かれたコードです。より良い書き方があるかどうかはわかりませんが、SQL Server 2000 ではうまく動作するのに、SQL Server 2005 では完全に内破してしまう理由がわかりません。

4

3 に答える 3

5

DISTINCT は並べ替えを引き起こし、IN はクエリ全体を評価します。このバージョンはどのように機能しますか:

SELECT OnProjAsMgr = CASE WHEN EXISTS 
  (SELECT 1 FROM dbo.ProjMgr WHERE ProjMgrID = TeamMember.ID)
  THEN 'Yes' 
  ELSE 'No' 
  END
FROM dbo.TeamMember;

それでもうまくいかない場合は、インデックスが欠落していると思われ、インデックスなしではクエリはうまく機能しません。

于 2012-09-11T20:38:43.917 に答える
1

「より良い」方法についてはわかりませんが、試すことができる別の方法を次に示します。

SELECT ... other fields you want ...,
       CASE WHEN ProjMgr.ProjMgrID IS NULL
            THEN 'No'
            ELSE 'Yes'
        END AS OnProjAsMgr
  FROM TeamMember
  LEFT
 OUTER
  JOIN ProjMgr
    ON ProjMgr.ProjMgrID = TeamMember.ID
;

ノート:

  • 一部の DBMS では、これはクエリよりもはるかに優れたパフォーマンスを発揮しますが、クエリが SQL Server 2000 で既に正常に動作していることを考えると、SQL Server 2005 でパフォーマンスが向上するかどうかはわかりません。試してみる必要があると思います。それ。
  • あなたのクエリは を使用していますSELECT DISTINCT ProjMgrID FROM ProjMgr。それが実際に異なる場合、つまりinSELECT ProjMgrID FROM ProjMgrの値が実際に重複している場合、上記のクエリは、重複ごとに個別のレコードを提供するため、正確には同じではありません。その場合、句を追加する必要がある場合があります。ProjMgrIDProjMgrGROUP BY
  • さらに言えば、 ifSELECT DISTINCT ProjMgrID FROM ProjMgrがデータの場合と同等であるSELECT ProjMgrID FROM ProjMgrと思われますが、オプティマイザーにも影響を与える可能性があるため、 を削除することも価値があるDISTINCTかもしれません。
于 2012-09-11T20:38:30.240 に答える
-1
SELECT (
    CASE WHEN P.ID IS NULL THEN 'No' ELSE 'Yes' END
) AS OnProjAsMgr
FROM TeamMember AS T 
LEFT OUTER JOIN ProjMgr AS P ON T.ID=P.ID
于 2012-09-11T20:41:31.033 に答える