Линк Дата Перформанс Смерть - PullRequest
3 голосов
/ 25 февраля 2010

У меня есть база данных, в которой хранятся даты, разбитые на int. То есть День, месяц и год хранятся отдельно в разных столбцах.

В существующих запросах SQL используется метод:

DATEADD (dd, - 1, DATEADD (мм, Z.LastMonth, DATEADD (гг, Z.LastYear - 1900, 0))) AS last_date

Я не могу изменить базу данных для хранения дат.

Если посмотреть дальше на функцию dateadd (), она конвертируется из целого числа (0). Linq to SQL не имеет аналогичной функциональности, т.е. Convert.ToDateTime (0). Это приводит к InvalidCastException.

Я попытался объединить строки, чтобы создать дату, но это WAYYYYY. разница во времени составляла около 10 минут.

Что еще я могу сделать? Я особенно не хочу начинать смешивать запросы SQL в проекте.

Спасибо.

Ответы [ 6 ]

3 голосов
/ 25 февраля 2010

Не могли бы вы просто написать:

table.Select(z => new DateTime(z.LastYear, z.LastMonth, z.LastDay));

Хорошо, я проверил это в Linqpad, и кажется, что Linq to SQL действительно решил сгенерировать какой-то странный запрос на преобразование символов. Я не совсем уверен, что это источник проблемы перфорирования, но вы можете вызвать проекцию, как это:

var dates = 
    (from z in table
     select new { Year = z.LastYear, Month = z.LastMonth, Day = z.LastDay })
    .AsEnumerable()
    .Select(d => new 
        {
            Date = new DateTime(d.Year, d.Month, d.Day),
            NextDate = new DateTime(d.Year, d.Month, 1).AddMonths(2).AddDays(-1)
        });

Это также даст вам последний день следующего месяца.

Если вы действительно видите такую ​​огромную производительность, разница, тем не менее, я бы рискнул предположить, что вы смотрите не в том месте, и есть что-то другое, что отличается. 90% всех проблем с производительностью, связанных с базой данных, происходят из-за плохой или несуществующей индексации или несаркируемых запросов.

3 голосов
/ 25 февраля 2010

Вы можете использовать linq to sql для сопоставления с пользовательским оператором SQL или хранимой процедурой, чтобы получить такую ​​же производительность SQL.

1 голос
/ 25 февраля 2010

Можете ли вы добавить представление в базу данных? Если вы можете, вы можете просто определить представление, которое будет выглядеть точно так же, как ваша таблица, за исключением реальной даты, поскольку оно поддерживается вашим запросом «превратите эти безумные столбцы в дату». Затем просто запросите это с помощью LINQ. Я не помню, есть ли в SQL Server интеллектуальное кэширование представлений, но если так, то оно может работать лучше, чем ваш прямой SQL.

1 голос
/ 25 февраля 2010

Вы можете отобразить функцию, чтобы сделать ее пригодной для использования в LINQ-TO-SQL: http://msdn.microsoft.com/en-us/library/bb546175.aspx

0 голосов
/ 25 февраля 2010

Примечание. Гораздо быстрее, чем конкатенация строк, создание массива символов и установка элементов массива символов самостоятельно. Это наиболее практично, если вы можете контролировать размер строк во время компиляции.

0 голосов
/ 25 февраля 2010

С точки зрения производительности, я предполагаю, что эта дата является вашим основным критерием фильтрации (тот, который вы ожидаете проиндексировать).

Если это так:

  • Убедитесь, что порядок столбцов в индексе - год, месяц, день.
  • Не отправляйте критерии Date в базу данных как DateTimes, вместо этого отправляйте целые числа. Если вы преобразуете столбцы таблицы в дату до фильтрации, индекс бесполезен.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...