かるあ のメモ

アクセスカウンタ

zoom RSS LoadOption と 遅延読み込み

<<   作成日時 : 2007/10/04 10:23   >>

ブログ気持玉 0 / トラックバック 1 / コメント 0

遅延ローディングの使い方(LINQ to SQL)(どっとねっとふぁん)より
以前のエントリで LINQ to SQL では遅延ロード(Lazy Load)について触れたと思います。確かに動きとしては素直な気がしますが、ラウンドトリップが多ければ多いほどパフォーマンスの面では気になってきます。

LINQ to SQL では LoadOption を指定することで簡単な読み込みの制御を行うことができます。何度か使っているこの表で動きを確認していきたいと思います。
画像


登録されているユーザのユーザIDと都道府県を表示します。
まずは普通にこんなコード
Using db = New comuplusDataContext()
    db.Log = Console.Out

    For Each u In db.User
        If u.PostAddress IsNot Nothing Then
            Console.WriteLine("UserID={0}, Address={1}", u.UserID, u.PostAddress.Address1)
        End If
    Next
End Using
この場合ユーザを検索する SQL が 1回
SELECT [t0].[UserID], [t0].[UserName], [t0].[PostNo], [t0].[PostSubNo], [t0].[UpdateDate]
FROM [dbo].[User] AS [t0]

ループ中に参照したユーザを検索する SQL がそのユーザ数分
13人に住所を設定しているとしたら 13回 SQL が実行される
SELECT [t0].[PostNo], [t0].[PostSubNo], [t0].[Address1], [t0].[Address2], [t0].[Address3], [t0].[UpdateDate]
FROM [dbo].[PostAddress] AS [t0]
WHERE ([t0].[PostNo] = @p0) AND ([t0].[PostSubNo] = @p1)

10人ぐらいだったらともかく何十人と検索するとデータベースにへそを曲げられそうです。

次に LoadOption を使ってみます。

Using db = New comuplusDataContext()
    db.Log = Console.Out

    Dim options = New System.Data.Linq.DataLoadOptions
    options.LoadWith(Of User)(Function(u As User) u.PostAddress)
    db.LoadOptions = options

    For Each u In db.User
        If u.PostAddress IsNot Nothing Then
            Console.WriteLine("UserID={0}, Address={1}", u.UserID, u.PostAddress.Address1)
        End If
    Next
End Using

User テーブルのデータをロードする場合に関連する PostAddress のデータも一緒にロードするように指定します。
この場合実行される SQL は一つだけです。
SELECT [t0].[UserID], [t0].[UserName], [t0].[PostNo], [t0].[PostSubNo], [t0].[UpdateDate], [t2].[test], [t2].[PostNo] AS [PostNo2], [t2].[PostSubNo] AS [PostSubNo2], [t2].[Address1], [t2].[Address2], [t2].[Address3], [t2].[UpdateDate] AS [UpdateDate2]
FROM [dbo].[User] AS [t0]
LEFT OUTER JOIN (
    SELECT 1 AS [test], [t1].[PostNo], [t1].[PostSubNo], [t1].[Address1], [t1].[Address2], [t1].[Address3], [t1].[UpdateDate]
    FROM [dbo].[PostAddress] AS [t1]
    ) AS [t2] ON ([t2].[PostNo] = [t0].[PostNo]) AND ([t2].[PostSubNo] = [t0].[PostSubNo])

ただ、ドメインモデルをLINQで構築する(その3)(開発思考実験日記)を見ると LoadOption を指定すれば一概に SQL の発行回数が少なくなるというわけではないようです。
確かに参照先のデータが少ない場合は遅延読み込みなしで全件読み込んだ後に、手動でリレーションを張ったほうが効率的な気はしますね。

テーマ

注目テーマ 一覧


月別リンク

ブログ気持玉

クリックして気持ちを伝えよう!
ログインしてクリックすれば、自分のブログへのリンクが付きます。
→ログインへ

トラックバック(1件)

タイトル (本文) ブログ名/日時
集合に対して繰り返し処理を行うときは取得したデータに対して行う...のがいいかも
何を当たり前のことを言っているといわれそうですが。(汗 こんな場合どんな結果を期待しますか? ...続きを見る
かるあ のメモ
2007/10/06 22:27

トラックバック用URL help


自分のブログにトラックバック記事作成(会員用) help

タイトル
本 文

コメント(0件)

内 容 ニックネーム/日時

コメントする help

ニックネーム
本 文
LoadOption と 遅延読み込み かるあ のメモ/BIGLOBEウェブリブログ
文字サイズ:       閉じる