Ef Linq запрашивает тайм-аут, но те же запросы менее 1 секунды в SSMS
Сначала я попробовалARITHABORT OFF
в SSMS это все еще меньше чем 1 секунда.
Я использую EntityFrameWork: 6.1.3 и уровень Azure Sql S1 (я попробую с уровнем 3 и сообщу, если что-то изменится.)
Я использую EF Profiler, чтобы получить сгенерированный sql из linq. Я запросил все linqs, которыми я поделился, все они менее чем за 1 секунду в SSMS.
У меня есть 3 миллиона записей на AuditLog Table. Один клиент с идентификатором 3 имеет 170 тыс. Записей, а другой клиент с идентификатором 35 - 125 записей. Я буду минимизировать код.
Модель AuditLog:
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 записей, это нормально.
Второй запрос: То же самое с первым, я просто включаю клиентов.
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 записей, это даст исключение тайм-аута.
Третий запрос: То же самое с первым запросом, но я соответствуюlong?
на где для 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 записей, это даст исключение тайм-аута.
Четвертый запрос: То же самое со вторым запросом, но я соответствуюlong?
на где для 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();
}
Результат противоположен второму запросу. если я попробую с клиентом, у которого есть 170k строк, это даст исключение тайм-аута. Если я попробую с клиентом, у которого 125 записей, это нормально.
Я действительно смущен. Почему внутреннее соединение или изменение параметра соответствия наlong?
меняются результаты? И почему все эти запросы выполняются в SSMS менее чем за 1 секунду и выдают ошибку на ef linq?
Ошибка:
{System.Data.SqlClient.SqlException (0x80131904): истекло время ожидания. Время ожидания истекло до завершения операции или сервер не отвечает. ---> System.ComponentModel.Win32Exception (0x80004005): Тайм-аут операции ожидания в System.Data.SqlClient.SqlConnection.OnError (исключение SqlException, логическое значение breakConnection, Action`1 wrapCloseInAction)
Обновление (19/04/2016):
ПослеИван Стоев предложение по комментариям.
Вы пробовали (только для проверки) использовать жестко закодированные 3 и 35 вместоcustomerId
переменная?
Я не получил никакой ошибки, и запросы были самыми быстрыми, как на SSMS.
Обновление (20/04/2016): Настоящая проблемаПараметр Sniffing, Когда я включил или изменил параметр на nullable, фактически я создал другие запросы и другие планы запросов. Я создал несколько планов с клиентом, у которого 125 записей, а другие - с клиентом, у которого 170 тыс. Записей этих 4 запросов. Вот почему я получил разные результаты.