4

SQLプロシージャをLinqに書き直そうとしていますが、小さなデータセットで動作する限り、すべてうまくいき、正常に動作します。これに対する答えはどこにも見つかりませんでした。つまり、クエリには 3 つの結合があり、2 つが areleft joinsで 1 つが is でありinner join、それらはすべて互いに/ツリーのように結合します。以下に、SQL プロシージャを示します。

SELECT ...
    FROM sprawa s (NOLOCK) 
        LEFT JOIN strona st (NOLOCK) on s.ident = st.id_sprawy
        INNER JOIN stan_szczegoly ss (NOLOCK) on s.kod_stanu = ss.kod_stanu
        LEFT JOIN broni b (NOLOCK) on b.id_strony = st.ident

お聞きしたいのは、これをLinqに翻訳する方法です。今のところ私はこれを持っています:

var queryOne = from s in db.sprawa
               join st in db.strona on s.ident equals st.id_sprawy into tmp1
               from st2 in tmp1.DefaultIfEmpty()
               join ss in db.stan_szczegoly on s.kod_stanu equals ss.kod_stanu
               join b in db.broni on st2.ident equals b.id_strony into tmp2
               from b2 in tmp2.DefaultIfEmpty()
               select new { };

問題ないようですが、SQL プロファイラーで確認すると、データベースに送信されるクエリは次のようになります。

SELECT ... FROM    [dbo].[sprawa] AS [Extent1] 
           LEFT OUTER JOIN [dbo].[strona] AS [Extent2] 
                ON [Extent1].[ident] = [Extent2].[id_sprawy]    
           INNER JOIN [dbo].[stan_szczegoly] AS [Extent3] 
                ON [Extent1].[kod_stanu] = [Extent3].[kod_stanu]    
           INNER JOIN [dbo].[broni] AS [Extent4] 
                ON ([Extent2].[ident] = [Extent4].[id_strony]) OR 
                (([Extent2].[ident] IS NULL) AND ([Extent4].[id_strony] IS NULL))

ご覧のとおり、両方の SQL クエリは少し異なります。効果は同じですが、後者は比類のないほど遅く動作します (1 秒未満から 30 分以上)。メイドもありunionますが、問題ないはずです。求められたら、コードを貼り付けます。

Linq ステートメントのパフォーマンスを向上させる方法や、適切に翻訳された方法で記述する方法についてアドバイスをいただければ幸いです。

4

1 に答える 1

1

私は解決策を見つけたと思います:

var queryOne = from s in db.sprawa
               join st in db.strona on s.ident equals st.id_sprawy into tmp1
               where tmp1.Any()
               from st2 in tmp1.DefaultIfEmpty()
               join ss in db.stan_szczegoly on s.kod_stanu equals ss.kod_stanu
               join b in db.broni on st2.ident equals b.id_strony into tmp2
               where tmp2.Any()
               from b2 in tmp2.DefaultIfEmpty()
               select new { };

つまりwhere table.Any()、各into tableステートメントの後。翻訳は改善されませんが、実行時間が 30 分近く (!) から約 5 秒に短縮されました。

ただし、結果セットの一部のレコードが失われる可能性があるため、これは慎重に使用する必要があります。

于 2013-08-21T13:42:50.900 に答える