Где делать пагинацию / фильтрацию?В базе данных или в коде? - PullRequest
4 голосов
/ 25 марта 2011

Я должен написать код для следующего метода:

public IEnumerable<Product> GetProducts(int pageNumber, int pageSize, string sortKey, string sortDirection, string locale, string filterKey, string filterValue)

Метод будет использоваться веб-интерфейсом и должен поддерживать разбиение на страницы, сортировку и фильтрацию. База данных (SQL Server 2008) насчитывает ~ 250 000 продуктов. Мой вопрос заключается в следующем: где я могу реализовать логику разбиения на страницы, сортировки и фильтрации? Должен ли я сделать это в хранимой процедуре T-SQL или в коде C #?

Я думаю, что лучше, если я сделаю это в T-SQL, но у меня получится очень сложный запрос. С другой стороны, выполнение этого в C # подразумевает, что мне нужно загрузить весь список продуктов, что тоже плохо ...

Есть идеи, что здесь лучше? Я пропускаю опцию?

Ответы [ 5 ]

4 голосов
/ 25 марта 2011

Вы определенно хотели бы, чтобы БД сделала это за вас.Перемещение ~ 250K записей из базы данных для каждого запроса будет огромными затратами.Если вы используете LINQ-to-SQL, методы Skip и Take сделают это ( здесь приведен пример ), но я неточно не знаю, насколько они эффективны.

1 голос
/ 25 марта 2011

Я бы определенно сделал это в хранимой процедуре примерно так:

SELECT * FROM (
     SELECT
          ROW_NUMBER() OVER (ORDER BY Quantity) AS row, *
     FROM Products
) AS a WHERE row BETWEEN 11 AND 20

Если вы используете linq, то методы Take и Skip позаботятся об этом за вас.

1 голос
/ 25 марта 2011

сегодня сам внедряю нумерацию страниц для своего сайта. Я сделал с хранимой процедурой, хотя я использую Entity-Framework. Я обнаружил, что выполнение сложного запроса лучше, чем получение всех записей и разбиение на страницы с кодом. Так что сделайте это с помощью хранимой процедуры. И я вижу вашу строку кода, которую вы прикрепили, я реализовал только таким же образом.

1 голос
/ 25 марта 2011

Я думаю, что другой (и потенциально лучший) вариант заключается в использовании более высокоуровневой инфраструктуры, которая защищает вас от сложности написания запросов.EntityFramework, NHibernate и LINQ (toSQL) вам очень помогут.Эта база данных, как правило, лучше всего подходит для вашего случая.

0 голосов
/ 25 марта 2011

Определенно в БД для предпочтения, если это вообще возможно.

Иногда вы можете немного смешаться, например, если у вас есть результаты, возвращаемые функцией базы данных (не хранимая процедура, функции могут быть частями больших запросов способами, недоступными хранимым процедурам), тогда вы можете использовать другую функцию. order и paginate, или, возможно, Linq2SQL или аналогичный вызов для страницы результатов из указанной функции, выдающий правильный SQL по мере необходимости.

Если вы, по крайней мере, можете выполнить упорядочивание в базе данных и, как правило, захотите только первые несколько страниц (довольно часто это происходит при реальном использовании), то вы можете по крайней мере иметь разумную производительность для этих случаев, так как достаточно строк. чтобы перейти к нужным строкам, а затем взять их, необходимо загрузить их из БД. Вам, конечно, все еще нужно проверить, что производительность является разумной в тех редких случаях, когда кто-то действительно ищет страницу 1,2312!

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

...