LINQ to SQL, нумерация страниц и COUNT (*) - PullRequest
6 голосов
/ 12 февраля 2010

Я использую класс PagedList в своем веб-приложении, с которым многие из вас могут быть знакомы, если вы что-то делали с ASP.NET MVC и LINQ to SQL. О нем пишут Роб Конери , и подобное воплощение было включено в такие вещи, как Nerd Dinner и т. Д. Это прекрасно работает, но мой администратор БД поднял опасения по поводу потенциальных будущих проблем с производительностью ,

Его проблема связана с SELECT COUNT (*), который выдается в результате этой строки:

TotalCount = source.Count();

Любое действие, в котором данные разбиты на страницы, запускает дополнительный запрос (как показано ниже) в результате вызова метода IQueryable.Count ():

SELECT COUNT(*) AS [value] FROM [dbo].[Products] AS [t0] 

Есть ли лучший способ справиться с этим? Я подумал об использовании свойства Count класса PagedList для получения количества элементов, но понял, что это не сработает, поскольку он учитывает только количество отображаемых элементов (но не общее количество).

Насколько сильно это повлияет на производительность моего приложения, когда в базе данных много данных?

Ответы [ 4 ]

8 голосов
/ 13 февраля 2010

iirc Этот материал является частью статистики индекса и должен быть очень эффективным, вы должны попросить своего администратора баз данных обосновать его опасения, а не преждевременно оптимизировать.

2 голосов
/ 14 октября 2010

На самом деле, это довольно распространенная проблема с Linq.

Да, статистика индекса будет использоваться, если оператор был только SELECT COUNT(*) AS [value] FROM [dbo].[Products] AS [t0], но в 99% случаев он также будет содержать операторы WHERE.

Таким образом, в основном выполняются два оператора SQL:

  1. SELECT COUNT(*) AS [value] FROM [dbo].[Products] AS [t0] WHERE blah=blah and someint=500

  2. SELECT blah, someint FROM [dbo].[Products] AS [t0] WHERE blah=blah and someint=500

Вы начинаете получать проблемы, если таблица часто обновляется, поскольку COUNT(*), возвращаемый в первом операторе, не равен второму оператору ... это может вернуть сообщение об ошибке «Строка не найдена или изменена».

1 голос
/ 12 января 2012

(PS Я знаю, что вы говорите о MsSQL, однако)

Я не администратор баз данных, но подсчет (*) в MySQL является настоящим ударом по производительности. Простое изменение этого значения на счет (ID) действительно улучшает скорость.

Я сталкивался с этим, когда запрашивал таблицу с очень большими данными GLOB (Изображения). Инструмент запроса около 15 секунд для загрузки. Изменение запроса на count (id) уменьшило запрос до 0,02. Все еще немного медленно, но чертовски лучше.

Я думаю, что это то, к чему стремится администратор базы данных. Тогда я заметил, что при отладке Linq оператор, который считает, занимает очень много времени (1 секунда), чтобы перейти к следующему оператору.

Основываясь на своих выводах, я должен согласиться с утверждениями администратора базы данных ...

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

Некоторые базы данных (Oracle, Postgresql, SQL Server, я думаю) ведут учет количества строк в системных таблицах; хотя иногда они точны только до того момента, когда статистика обновлялась в последний раз (Oracle). Вы можете использовать этот подход, если вам нужна только довольно точная, но не точная метрика.

Какую базу данных вы используете или она отличается?

...