4

更新:SQLクエリは機能していますが、それでもlinq2sqlへの変換に問題があります。以下のコードをご覧ください。

大量のデータをプルしているlinqクエリがありますが、SQLサーバーにかかる負荷が原因でタイムアウトになることがあります。より効率的なデータの取得(インデックスの追加など)に取り組むつもりですが、サブクエリを使用するよりもgroupbyを使用する方が効率的であるとも聞いています。group byの方が効率的でしょうか?もしそうなら、以下のクエリはgroup byでどのようになりますか?私はまだgroupbyに精通していません。ラムダを使用しないでください

編集:まだ遅く、タイムアウトする可能性のある新しいクエリ:

  var query = (from s in db.ZipCodeServiceAvailabilities
                         join a in db.pdx_apart_views on s.ZipCode equals a.Zip_Code.Substring(0, 5)  into a_join
                         from a in a_join.DefaultIfEmpty()
                         join b in db.ZipCodeBoundaries on s.ZipCode equals b.ZipCode  into b_join
                         from b in b_join.DefaultIfEmpty()
                         where
                           (s.IsServiced == 1 &&
                            b.Ordering % 10 == 0 &&
                           s.State == "AL")
                         group new { s, b, a } by new
                         {
                             s.ZipCode,
                             s.IsServiced,
                             b.Longitude,
                             b.Latitude,
                             b.Ordering
                         } into g
                         orderby
                           g.Key.ZipCode,
                           g.Key.Ordering
                         select new
                         {
                             g.Key.ZipCode,
                             apartCount = g.Count(p => p.a.Apartment_complex != null),
                             Longitude = g.Key.Longitude,
                             Latitude = g.Key.Latitude
                         }).ToArray();

編集:linq2sqlで必要なSQLで動作するクエリ(非常に高速):

select s.ZipCode, count(distinct ident) ApartCount, b.Longitude, b.Latitude from ZipCodeServiceAvailability s
                    left join pdx_apart_view
                          on s.ZipCode = left([Zip Code], 5)
                    left join ZipCodeBoundaries b
                          on s.ZipCode = b.ZipCode


  Where  IsServiced = 1 and and Ordering % 10 = 0 and State = 'AL'

  Group By s.ZipCode, IsServiced, b.Longitude, b.Latitude, b.Ordering
  Order by s.ZipCode, b.Ordering

非常に遅い元のクエリ:

var zips = (from s in db.ZipCodeServiceAvailabilities
    join b in db.ZipCodeBoundaries on s.ZipCode equals b.ZipCode
    where (s.IsServiced == service 
        && b.Ordering % 10 == 0 
        && s.State.Contains(state))
    orderby b.ZipCode
    select new
    {
        zipCode = b.ZipCode.Trim(),
        latitude = b.Latitude,
        longitude = b.Longitude,
        apartCount = (from a in db.pdx_apart_views
                      where a.Zip_Code.Remove(5) == b.ZipCode
                      select a.Apartment_complex).Count()

    }).ToArray();
4

2 に答える 2

2

一般的なグループ化に慣れていないということですか、それともlinqのコンテキストでのみ知っているということですか?

エンティティ定義がない場合は、linqよりもプレーンSQLを作成する方が簡単だと思います。以下は、SQLで探しているものです。linqに戻すのはかなり簡単です。

select
  b.ZipCode zipCode,
  b.Latitude latitude,
  b.Longitude longitude,
  count(a.Apartment_complex) apartCount
from 
  ZipCodeServiceAvailabilities s
join ZipCodeBoundaries b 
  on s.ZipCode = b.ZipCode
left join pdx_apart_views a
  on substring(a.Zip_Code, 1, 5) = b.ZipCode
group by
  ZipCode,
  Latitude,
  Longitude
于 2013-02-14T02:01:36.823 に答える
1

インデックスを壊さずにlinq2sqlのleft[(zip code)、5]sqlメソッドを複製する方法はありませんでした。答えは、まっすぐなado.netを使用して、すべてのSQL機能を取得することでした。

于 2013-02-16T19:09:57.227 に答える