linq: производительность SQL в высоконагруженных веб-приложениях - PullRequest
2 голосов
/ 31 марта 2010

Я начал работать с LINQ к SQL несколько недель назад. Я получил очень устал работать с сервером SQL непосредственно через запросы SQL (SqlDataReader, SqlCommand и все это хороший материал).

После того, как слух о LINQ к SQL и MVC Я быстро перешел все мои проекты в эти технологии. Я ожидал, что LINQ к SQL работы медленнее, но suprisongly оказался довольно быстро, в первую очередь потому, что я всегда забыл закрыть свои связи при использовании DataReaders. Теперь я не придется беспокоиться об этом.

Но есть одна проблема, которая действительно беспокоит меня. Там одна страница, которая просила тысячи раз в день. Система получает данные в начале работы с ним и обновляет его. В первую очередь эти обновления ++ @ - (увеличение и уменьшение значений). Я имел обыкновение делать это так

значение SET UPDATE таблица = значение + 1 WHERE ID = @ Я бы

Он работал без проблем, очевидно. Но с помощью LINQ к SQL данные берутся в начале, переехал в класс, изменились, а затем сохраняются.

Stats.registeredusers ++; Db.submitchanges ();

Скажем, там было 100 000 пользователей. Linq будет говорить «пусть это будет 100 001» вместо «пусть это будет увеличено на 1».

Но если значение пользователей уже увеличилось (что происходит в моем месте все время), то LINQ будет как упс, это значение уже 100 001. Все, что я брошу исключение "

Вы можете изменить это поведение так, что он не будет бросать исключение, но он все равно не будет установлено значение 100 002.

Как я уже сказал, это случилось со мной все время. Значение стас был увеличен два раза в секунду в среднем. Я просто пришлось переписать этот кусок кода с классической Ado сети.

Итак, мой вопрос заключается в том, как вы можете решить эту проблему с помощью LINQ

Ответы [ 3 ]

5 голосов
/ 31 марта 2010

Для этих типов «запросов только для записи» я обычно использую хранимую процедуру. Вы можете перетащить хранимую процедуру в конструктор и выполнить ее через класс Linq to SQL DataContext (он будет добавлен как метод).

Извините за банальный ответ, но это действительно так просто; не нужно искать необработанные объекты ADO.NET SqlCommand и т.п., просто импортируйте SP и все готово. Или, если вы хотите перейти на действительно ad-hoc, используйте метод ExecuteCommand, например:

context.ExecuteCommand("UPDATE table SET value = value + 1 WHERE ID = {0}", id);

(Но не злоупотребляйте этим, поддерживать его может быть сложно, поскольку логика больше не содержится в вашем экземпляре DataContext. И прежде чем кто-либо скажет, что это уязвимость внедрения SQL, обратите внимание, что 1012 * / ExecuteQuery - это умные методы, которые превращают это в параметризованный оператор / запрос.)

4 голосов
/ 31 марта 2010

Linq to Sql поддерживает «оптимистичный» параллелизм из коробки. Если вам нужен более жесткий контроль, вы можете добавить столбец Timestamp к вашей таблице, и Linq to Sql будет использовать эту метку времени для усиления параллелизма.

http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2008/07/01/10557.aspx

Однако, как указывает Мортен в комментариях ниже, это решение не будет работать хорошо. Конечно, вы всегда можете использовать ADO.NET для обновления значения, как вы делали раньше; это никак не повлияет на работу ваших запросов Linq.

0 голосов
/ 31 марта 2010

Вы можете отключить параллелизм для этого свойства, изменив значение UpdateCheck:

http://msdn.microsoft.com/en-us/library/bb399394(v=VS.90).aspx

Грязно, если вы используете сгенерированный код и дизайнер, но я думаю, что это единственный способ сделать это.

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