これが私の設定です:
- .NET 4.0でのコンパイル(これより高くすることはできません)
- Oracle11gR2データベースに対するEntityFrameworkの使用
- ODP.NET11.2.0.3.20の使用
- Visual Studio2012UltimateおよびOracleDeveloperTools for VisualStudio11.2.0.3.20の使用
- LINQtoEntityを使用してクエリを実行する
これが私の問題です。OracleDeveloperToolsforVisual Studio(11.2.0.3.20)で作成したエンティティがいくつかあります。一部のエンティティは、かなり迅速に結果を返します。ただし、2,000万を超えるレコードを含むビュー/テーブルに対してクエリを実行している他のユーザーの場合、この単純なクエリの結果を返すのに常に10分かかります(今回は単体テストで確認しました)。
var member = (from m in context.Members
where m.MemberID.Equals(memberId, StringComparison.OrdinalIgnoreCase)
select m).FirstOrDefault();
以前はDevartdotConnectfor Oracleを使用していましたが、これは非常にうまく機能しました...しかし、私の会社はこの製品のライセンスを更新しておらず、VisualStudio用の新しいOracleDeveloperToolsを使用して作業を行うように指示しました。
回避策として、OracleCommand
ODP.NET(Oracle.DataAccess.dll)が提供するデータベースに直接接続しましたが、1秒以内に結果が返されます。管理クライアントを使用してデータベースに対して直接他のクエリを実行するのと同じです。
なぜこれが起こっているのかについての私の最も良い推測は、おそらくエンティティがデータベース全体をメモリにロードし、それに対してクエリを実行しているということです...これは恐ろしいことですが、それが起こっているとは本当に信じていません。
誰かがこれが起こっている理由と、すべてのDBクエリを手動で書き直す必要がないようにEntityを使用して修正する方法を説明できますか?
更新:
それで、クエリが完了するのに10分かかった理由を見つけました。私は(データベースの経験がほとんどないので)これをEDMXファイルに入れていました。
...
<EntityContainer Name="MyStoreContainer">
<EntitySet Name="MY_TABLE" EntityType="MyDB.Store.MY_TABLE" store:Type="Views" store:Schema="MYUSERNAME" store:Name="MY_TABLE">
<DefiningQuery>
SELECT
"MY_TABLE"."COL1" AS "COL1",
"MY_TABLE"."COL2" AS "COL2",
"MY_TABLE"."COL3" AS "COL3",
"MY_TABLE"."COL4" AS "COL4",
"MY_TABLE"."COL5" AS "COL5",
"MY_TABLE"."COL6" AS "COL6",
"MY_TABLE"."MEMBERSHIP_ID" AS "MEMBERSHIP_ID",
"MEMBERS"."EXTRA_INFO1" AS "EXTRA_INFO1",
"MEMBERS"."EXTRA_INFO2" AS "EXTRA_INFO2"
FROM "MYUSERNAME"."MY_TABLE" "MY_TABLE"
LEFT JOIN "MYUSERNAME"."MEMBERS" ON "MY_TABLE"."MEMBERSHIP_ID" = "MEMBERS"."MEMBER_ID"
</DefiningQuery>
</EntitySet>
...
管理クライアントに直接クエリを実行する場合も、LEFT JOIN
約10分かかることがわかりました。それで私はLEFT JOIN
取り出しました...そして今私はスピードの増加を見ます。これがキャッチです。このEntitySetは、応答が非常に遅いときにクエリを実行していたEntitySetではありませんでした。を使用して手動でコードを記述した場合でも、応答は約4〜5倍速くなりますOracleCommand
。
エンティティが物事をそれほど遅くしている理由と、この左結合クエリにアクセスしていないときを誰かが説明できますか?