Linq. Помоги мне настроить это! - PullRequest
3 голосов
/ 30 апреля 2010

У меня есть запрос linq, который вызывает проблемы с тайм-аутом. По сути, у меня есть запрос, который возвращает первые 100 результатов из таблицы, содержащей примерно 500 000 записей.

Вот запрос:

using (var dc = CreateContext())
        {
            var accounts = string.IsNullOrEmpty(searchText)
                            ? dc.Genealogy_Accounts
                                .Where(a => a.Genealogy_AccountClass.Searchable)
                                .OrderByDescending(a => a.ID)
                                .Take(100)
                            : dc.Genealogy_Accounts
                                .Where(a => (a.Code.StartsWith(searchText)
                                            || a.Name.StartsWith(searchText))
                                            && a.Genealogy_AccountClass.Searchable)
                                .OrderBy(a => a.Code)
                                .Take(100);
            return accounts.Select(a => 
        }
    }

Как ни странно, это первый запрос linq, который вызывает тайм-аут. Я подумал, что при выполнении операции «Take» нам не нужно сканировать все 500 тыс. Записей. Тем не менее, это должно быть то, что происходит. Я предполагаю, что объединение, чтобы найти то, что «доступно для поиска», вызывает проблему. Я не могу денормализовать таблицы ... поэтому мне интересно, есть ли способ переписать запрос linq, чтобы он быстрее возвращался ... или мне просто нужно написать этот запрос как хранимую процедуру (и если да, то как это может выглядеть). Спасибо.

Ответы [ 2 ]

14 голосов
/ 30 апреля 2010

Ну, для начала я бы выяснил, какой запрос генерируется (в LINQ to SQL вы устанавливаете Журнал в контексте данных), а затем профилируете его в SQL Server Management Studio. Играйте с этим там, пока не найдете что-то достаточно быстрое (изменив запрос или добавив индексы), и если вам пришлось изменить запрос, подумайте, как представить это в LINQ.

Я подозреваю, что проблема в том, что вы комбинируете OrderBy и Take - это означает, что потенциально необходимо выяснить все результаты, чтобы определить, как будут выглядеть первые 100 , Code проиндексирован? Если нет, попробуйте проиндексировать это - это может помочь, позволив серверу рассматривать записи в порядке, в котором они будут возвращены, поэтому он может остановиться после того, как будет найдено 100 записей. Вы должны посмотреть на индексы и для других столбцов.

3 голосов
/ 30 апреля 2010

Значение Take(100) переводится как «Выбрать 100» и т. Д. Это помогло бы, если бы ваша проблема заключалась в огромном наборе результатов, где возвращалось много столбцов. Могу поспорить, что ваша проблема - сканирование таблицы в результате запроса. В этом случае .Take(100) может совсем не помочь.

Итак, вероятный виновник такой же, как если бы вы делали SQL с использованием ADO.NET: Как ваши индексы ? Поля, в которых ведется поиск, не имеют хороших индексов? Это может привести к резкому снижению производительности по сравнению с запросами, в которых do используют хорошие индексы. Добавьте индекс, который включает Code и Name и посмотрите, что произойдет. Если вы не используете индекс для Code, это гарантированно из-за Order By. Кроме того, какие поля связывают Genealogy_Accounts и Genealogy_AccountClass ? Отсутствие указателя на любом столе может помешать. (Я думаю, индекс, включающий Searchable вряд ли поможет.)

Используйте SQL Profiler , чтобы увидеть фактический выполняемый запрос (хотя вы можете сделать это и в VS) и посмотреть, насколько он действительно плох на сервере.

Проблема может заключаться в том, что LINQ делает какую-то глупость при создании запроса, но, вероятно, это не так. Мы находим, что LINQ-to-SQL часто делает лучшие запросы, чем мы. Даже если это выглядит глупо, обычно это очень эффективно . Вы можете поместить SQL в Query Analyzer и проверить план запроса. Затем перепишите SQL, чтобы сделать его более простым для людей, и посмотрите, улучшит ли он что-то - я уверен, что этого не произойдет. Я думаю, вы все равно увидите сканирование таблицы , указывающее, что с вашим индексом что-то не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...