まず、ARITHABORT OFF
をSSMSで試したところ、まだ1秒未満でした。Ef LinqのクエリはSSMSで1秒未満です。
:6.1.3とAzureのSQLのS1層(IがTier 3にしようとすると、何かが変わるかどうかを知るようになる。)
私は、LINQからSQLを生成取得するEFプロファイラを使用しています。私は共有しているすべてのlinqを照会しました。それらはすべてSSMS上で1秒未満です。
私はAuditLogテーブルに300万の記録を持っています。 ID 3の顧客は170Kのレコードを持ち、ID 35の顧客は125のレコードを持っています。コードを最小限に抑えます。
監査ログモデル:
public class AuditLog
{
public long? CustomerId { get; set; }
[ForeignKey("CustomerId")]
public virtual CustomerSummary Customer { get; set; }
[Required]
[Index]
public DateTime CreatedDate { get; set; }
}
まずクエリ:
if (customer != null)
{
var customerId = customer.Id;
var result= Dbset.Where(x => x.CustomerId == customerId).OrderByDescending(x => x.CreatedDate).Skip(0).Take(25).ToList();
}
私は170Kの行を持っている顧客としようとすると、それが例外を時間を与えます。 125件のレコードを持っている顧客と一緒に試してみるといいですね。
第2クエリ:これは最初のものと同じですが、私は顧客を含んでいます。
if (customer != null)
{
var customerId = customer.Id;
var result= Dbset.Where(x => x.CustomerId == customerId).OrderByDescending(x => x.CreatedDate).Skip(0).Take(25).Include(x => x.Customer).ToList();
}
結果は最初のクエリと逆です。 170k行の顧客と一緒に試してみるといいですね。 125レコードある顧客と一緒に試してみると、タイムアウト例外が発生します。
第3のクエリ:これは最初のクエリと同じですが、私はとcustomerIdの一致します。
if (customer != null)
{
long? customerId = customer.Id;
var result= Dbset.Where(x => x.CustomerId == customerId).OrderByDescending(x => x.CreatedDate).Skip(0).Take(25).ToList();
}
結果は最初のクエリとは逆です。 170k行の顧客と一緒に試してみるといいですね。 125レコードある顧客と一緒に試してみると、タイムアウト例外が発生します。
第4のクエリ:第2のクエリと同じですが、私はとcustomerIdの一致します。
if (customer != null)
{
long? customerId = customer.Id;
var result= Dbset.Where(x => x.CustomerId == customerId).OrderByDescending(x => x.CreatedDate).Skip(0).Take(25).Include(x => x.Customer).ToList();
}
結果は2番目のクエリと逆です。 170k行の顧客と一緒に試してみると、タイムアウト例外が発生します。 125件のレコードを持っている顧客と一緒に試してみるといいですね。
私は本当に混乱しています。なぜ内的に参加するか、または一致するパラメータをlong?
に変更すると結果が変わるのですか?そして、なぜこのすべてのクエリがSSMSで1秒以下で実行され、ef linqでエラーが発生するのですか?
エラー:
{System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
更新(19/04/2016):コメントの
Ivan Stoev後の提案。
Have you tried (just for the sake of test) using hardcoded 3 and 35 instead of
customerId
variable?
SSMSのようにエラーは発生せず、クエリも最速です。
更新(20/04/2016):実際の問題はパラメータスニッフィングです。パラメータをnullableに含めたり変更したりすると、実際に別のクエリと別のクエリプランが作成されました。私は125のレコードを持つ顧客と、これらの4つのクエリの170kのレコードを持つ顧客とのいくつかのプランを作成しました。だから私は別の結果を得ました。
どのようにして結果を比較しているようなあなたのスニペットを更新しますか?あなたはEFによって生成されたSQLと比較しているのですか、または自分で書いていますか? –
EFによって生成されたSQL。 –
それは面白いです。使用しているEFのバージョンも指定すると便利です。 –