2010-05-01 3 views
1

Я использую LINQ to SQL и вижу, как работает мой процессор. См. Снимок экрана ниже. У меня есть три вопроса:LINQ to SQL: Слишком много использования ЦП: что происходит, когда есть несколько пользователей

  • Что я могу сделать, чтобы уменьшить это использование ЦП. Я сделал профилирование и в основном удалил все. Будет ли каждый оператор LINQ to SQL скомпилировать запрос?

  • Я также обнаружил, что даже с скомпилированными запросами простые операторы типа ByID() могут занимать 3 миллисекунды на сервере с 3,25 ГБ оперативной памяти 3,17 ГГц - это будет замедляться на менее мощном компьютере. Или будет скомпилированный запрос быстрее, чем больше он используется?

  • Использование ЦП (на локальном сервере составляет 12-15%) для одного пользователя будет умножаться на количество пользователей, обращающихся к серверу, - когда приложение помещается на живой сервер. то есть 2 пользователя за раз будут иметь значение 15 * 2 = 30% использования ЦП. Если это так, мое приложение ограничено максимум 4-5 пользователями одновременно. Или LINQ to SQL .net не использует некоторое использование ЦП. alt text http://www.freeimagehosting.net/uploads/5f10e1f694.png

+1

индексы, индексы, индексы ... –

+1

Можете ли вы разместить SQL для запроса, который, по вашему мнению, является причиной проблем? –

+1

Является ли ваш SQL Server на той же машине? Вы уверены, что LINQ to SQL (.NET) питается вашим процессором или это ваш SQL Server? – Steven

ответ

6

профиля. Профиль. Профиль.

Профиль, чтобы узнать, какой именно запрос использует большинство ресурсов и повышает производительность этого запроса. Вы можете использовать свойство Log для DataContext для просмотра SQL - см. this article. Вы можете получить планы запросов для запроса в SQL Server - см. this article.

Примеры способов улучшить запрос:

  • Добавить недостающие индексы.
  • Перепишите запрос, чтобы воспользоваться теми индексами, которые уже есть.
  • Не извлекайте слишком много данных для каждого запроса - используйте пейджинг и получайте только несколько строк по запросу. Не извлекайте поля, которые вам не нужны.
  • Не извлекайте слишком мало данных для запроса - не делайте цикл, выбирающий одну строку за раз. Извлеките сразу несколько строк.

После того, как вы это сделали, снова профиль снова, чтобы проверить, улучшилось ли качество этого запроса. Если нет, повторите, пока не появится.

Затем профиль снова, чтобы узнать, что представляет собой следующий запрос на убийство, и повторите этот процесс, пока ваша производительность не будет приемлемой.

Вы говорите, что у вас уже есть профилированный, но вы не размещали какую-либо профилирующую информацию, такую ​​как запросы, планы запросов, время выполнения, частоту запросов и т. Д. Без дополнительной информации о профилировании мы можем только догадываться.

+0

Индекс на что? Таблица в SQL-сервере. LINQ to SQL даже заботится об индексах на таблицах - здесь нет здесь http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/ad8cc0d5-e1a3-4333-b0a1-1d67c406a6c7 – soldieraman

+0

@soldieraman: LINQ to SQL преобразует выражения запросов в SQL. SQL-сервер создает планы запросов для этих операторов SQL, основываясь на том, какие индексы доступны и на основе статистики для таблицы. Вы можете записывать операторы SQL, отправленные в базу данных, назначая что-то свойству Log вашего контекста. –

+1

Участие LINQ в индексах вашей базы данных совпадает с любым другим внешним объектом - конечным пользователем, разработчиком, ADO.NET, ODBC и т. Д. Если вы создали индексы как часть вашей схемы базы данных, LINQ будет использовать их, поскольку ваша база данных уже настроенных для их использования. –

1

Скомпилированные запросы не будут «быстрее» с большим использованием. Основным преимуществом скомпилированных запросов является сохранение необходимости того, чтобы движок LINQ выполнял каждый раз процесс перевода каждый раз, когда он вызывается.

Что касается использования ЦП, если это ваша машина разработки, шансы очень хороши в том, что что-то еще происходит, чтобы вызвать такую ​​высокую активность. Даже если это выделенный сервер базы данных, я бы предложил использовать SQL Profiler для изучения того, какие операторы генерируются вашими запросами LINQ. Это может потребовать настройки вашей схемы, кода или настроек базы данных, чтобы вернуть использование более приемлемого уровня.

0
  1. Есть ли общие вопросы, которые можно кэшировать?
  2. Можно ли переписать запросы linq
  3. Выполняется ли большая часть обработки запросов на веб-сервере или в SQL?
  4. Вы используете оба SQL-сервера и веб-сервер в одном окне? У вас есть тестовая среда, которая имитирует производственную среду?
3

Я заметил подобное поведение с некоторыми приложениями здесь; Используя ANTS Profiler, мы сократили использование нашего процессора до того, как он находится в коде Linq to SQL. Мы обнаружили несколько основных мест, в которых это становится проблемой:

  1. Комплексные запросы Linq to SQL. Использование нескольких соединений и ограничений предложения и т. Д. Проблема в том, что механизм Linq to SQL должен преобразовать оператор C# в инструкцию SQL. Я считаю, что это преобразование по умолчанию может быть повторно использовано, если тот же код вызывается одним и тем же DataContext, но если вы создаете новый DataContext для каждого исполнения, тогда код преобразования интенсивного процессора выполняется каждый раз. Это можно решить, заменив сложный запрос Linq на SQL хранимой процедурой или используя предварительно скомпилированный запрос Linq to SQL (Here's a blog post showing how to create a compiled query).
  2. Отражение на основе имущества. Мы обнаружили, что простые запросы, такие как DataContext.Orders.FirstOrDefault(o => o.OrderID = orderID), могут быть очень интенсивными, поскольку они используют отражение для установки всех свойств возвращаемых значений из запроса. Мы не исследовали это выше этого пункта; Мы просто заменили часть нашего кода на основе Linq на SQL стандартным C# Data Access (например, SqlCommand, SqlClient) с помощью написанного вручную кода, чтобы вытащить соответствующие данные столбца в соответствующие свойства, но только в тех местах, которые ANTS рассказывали нам, важный. Выполнение этого изменения в целом значительно снизило загрузку ЦП (например, с 2000 мсек загрузки процессора до 39 мс).
  3. Общая проблема производительности Linq (не относится к Linq to SQL); В то время как записи запросов Linq приводят к выявлению большего количества кода, чем к аналогичным итеративным подходам, мы обнаружили, что иногда запросы становятся очень неэффективными (обычно, повторяя несколько раз несколько раз или создавая декартово произведение, где это действительно не нужно) , У меня нет никаких примеров этого с моей точки зрения, но ANTS также помог найти эти проблемы (как правило, ищет чрезвычайно высокие показатели хитов для определенной строки кода). Обычно они могут быть исправлены с небольшими изменениями в запросе Linq (или в некоторых случаях заменяя запрос Linq инструкциями пары).

Возможно, важно отметить, что наше использование Linq to SQL основано на файлах DBML, создаваемых графическим интерфейсом, поэтому атрибуты украшали классы со всей информацией о сопоставлениях столбцов и т. Д.

Это именно то, что мы нашли относительно Linq to SQL; Мне было бы интересно узнать, что такое другой опыт. Я настоятельно рекомендую ANTS Performance Profiler для определения того, где загрузка процессора сосредоточена в вашем приложении; Обратите внимание: если высокая загрузка центрального процессора основана на SQL (что, похоже, не так, как в вашем случае), ANTS, вероятно, не поможет (и остальная часть моего ответа :)).

1

Недавно мы развернули большое приложение электронной коммерции, использующее linq to sql, и опытное использование процессора очень похоже на то, что вы описываете.

После нескольких недель профилирования и отладки следов оказалось, что злодей был jit-компиляцией запросов во время выполнения.

Мы прошли через наш уровень данных и преобразовали все запросы в скомпилированные запросы, и наше использование ЦП мгновенно перешло от постоянного 100% к усреднению от 5% до 20% с некоторыми шипами до 80%, когда запросы сначала компилировались.

Смежные вопросы