私は比較的基本的なSQL文を実行しようとしていますが、いくつかの表を結合してグループ化し、集約関数で要約します。私はEF4で以下のLINQ文を使用する場合(一番下を参照)、それはいくつかの恐ろしいSQLを作成し、ジョインと集計を使用したLINQ文からの効率的なSQL?
select
p.LocationID,
NumReadings = count(*),
MinDate = min(t.[DateTime]),
MaxDate = max(t.[DateTime])
from Station p inner join Data pd on p.LocationID = pd.ReadingLocationID
inner join ApplicationDateTime t on t.ApplicationDateTimeID = pd.DateTimeID
group by p.LocationID
:私はこのようにSQLでそれを記述します。これを行うためのよりよい方法はありますか? EFナビゲーションプロパティを使用する代わりに明示的に結合を実行すると、さらに悪化します。
私は美学については気にしませんが、クエリの実行を見てみると、不良なSQLを実行するには3~4倍の時間がかかります。 (:いくつかの追加の複雑さは、他の参加として表さ継承関係のように、ここにありますが、それはちょうど別のネストレベルを引き起こし注)
from s in Station
select new DataSummary
{
ReadingLocationID = s.ReadingLocationID,
StationIdentifier = s.StationIdentifier,
NumReadings = s.Data.Count(),
MinDateLoaded = s.Data.Min(d => d.ApplicationDateTime.DateTime),
MaxDateLoaded = s.Data.Max(d => d.ApplicationDateTime.DateTime)
};
はここでSQLです。
SELECT
[Project3].[LocationTypeID] AS [LocationTypeID],
[Project3].[ReadingLocationID] AS [ReadingLocationID],
[Project3].[LocationIdentifier] AS [LocationIdentifier],
[Project3].[C1] AS [C1],
CAST([Project3].[C2] AS datetime2) AS [C2],
CAST([Project3].[C3] AS datetime2) AS [C3]
FROM (SELECT
[Project2].[ReadingLocationID] AS [ReadingLocationID],
[Project2].[LocationTypeID] AS [LocationTypeID],
[Project2].[LocationIdentifier] AS [LocationIdentifier],
[Project2].[C1] AS [C1],
[Project2].[C2] AS [C2],
(SELECT
MAX([Extent7].[DateTime]) AS [A1]
FROM [dbo].[Data] AS [Extent6]
INNER JOIN [dbo].[ApplicationDateTime] AS [Extent7] ON [Extent6].[DateTimeID] = [Extent7].[ApplicationDateTimeID]
WHERE [Project2].[ReadingLocationID] = [Extent6].[ReadingLocationID]) AS [C3]
FROM (SELECT
[Project1].[ReadingLocationID] AS [ReadingLocationID],
[Project1].[LocationTypeID] AS [LocationTypeID],
[Project1].[LocationIdentifier] AS [LocationIdentifier],
[Project1].[C1] AS [C1],
(SELECT
MIN([Extent5].[DateTime]) AS [A1]
FROM [dbo].[Data] AS [Extent4]
INNER JOIN [dbo].[ApplicationDateTime] AS [Extent5] ON [Extent4].[DateTimeID] = [Extent5].[ApplicationDateTimeID]
WHERE [Project1].[ReadingLocationID] = [Extent4].[ReadingLocationID]) AS [C2]
FROM (SELECT
[Extent1].[ReadingLocationID] AS [ReadingLocationID],
[Extent1].[LocationTypeID] AS [LocationTypeID],
[Extent1].[LocationIdentifier] AS [LocationIdentifier],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Data] AS [Extent3]
WHERE [Extent1].[ReadingLocationID] = [Extent3].[ReadingLocationID]) AS [C1]
FROM [dbo].[ReadingLocation] AS [Extent1]
INNER JOIN [dbo].[Station] AS [Extent2] ON [Extent1].[ReadingLocationID] = [Extent2].[LocationID]
WHERE ([Extent1].[LocationTypeID] = CAST('1' AS int)) AND ([Extent2].[LineID] = 'ACBB3FDF-116C-4E8E-AA80-B925E4922AC8')
) AS [Project1]
) AS [Project2]
)
ヘルプ!ありがとう。
うんざりすると、複雑すぎます。それはMinとMaxなしでどのように見えるのですか? – mattytommo
Linq2Sqlでクエリをテストしましたか?私の経験では、より良いSQLを生成します。 – Magnus
minとmaxを指定しないと、2つの "レベル"が削除されます。実際には各集約関数に対して1つのクエリを実行しているようです。また、私は結合テーブルからフィールドで "max()"をやっているかもしれません。私はすでにプロジェクトにEFを使用しているので、私は本当に切り替えることはできません。 – jrowe88