2010-02-12 4 views
6

Używam klasy PagedList w mojej aplikacji sieciowej, którą wielu z was może znać, jeśli robiliście coś z ASP.NET MVC i LINQ do SQL. Zostało ono napisane na blogu przez Rob Conery, a podobne wcielenie zawierało się w takich rzeczach jak Nerd Dinner itp. Działa to świetnie, ale mój DBA wzbudził obawy o potencjalne przyszłe problemy z wydajnością.LINQ do SQL Pagination i COUNT (*)

Jego problemem jest wokół select count (*), która zostanie wydane w wyniku tej linii:

TotalCount = source.Count(); 

Każda akcja, która wywoływana dane wystrzelić dodatkowe zapytania (jak poniżej) w wyniku Wywołania metody IQueryable.Count():

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

Czy istnieje lepszy sposób radzenia sobie z tym? Rozważałem użycie właściwości Count klasy PagedList, aby uzyskać licznik elementów, ale zdałem sobie sprawę, że to nie zadziała, ponieważ liczy się tylko liczba aktualnie wyświetlanych elementów (nie całkowita liczba).

Ile trafienia wydajności spowoduje to moją aplikację, gdy w bazie danych jest dużo danych?

Odpowiedz

8

Te rzeczy są częścią statystyk indeksu i powinny być bardzo wydajne, powinieneś poprosić administratora DBA o podporządkowanie swoich obaw, zamiast przedwcześnie optymalizować.

+2

Upvoted tak mocno, że złamał internet. ;) Jeśli dodatkowe kwerendy będzie przynieść wydajność bazy danych masz kilka poważnych problemów. – jfar

1

Niektóre bazy danych (Oracle, Postgresql, SQL Server, jak sądzę) prowadzą rejestr liczby wierszy w tabelach systemowych; choć czasami są one dokładne tylko do momentu, w którym statystyki zostały ostatnio odświeżone (Oracle). Możesz użyć tego podejścia, jeśli potrzebujesz tylko dość dokładnych, ale nie ścisłych danych.

Którą bazę danych używasz, czy to się zmienia?

+0

SQL Server 2005 –

2

W rzeczywistości jest to dość powszechny problem z Linq.

Tak, statystyki indeksu zostaną użyte, jeśli oświadczenie było tylko SELECT COUNT(*) AS [value] FROM [dbo].[Products] AS [t0], ale 99% czasu będzie zawierać również instrukcje WHERE.

Więc w zasadzie dwie instrukcje SQL są wykonywane:

  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

rozpocząć odbieranie problemy, jeśli tabela jest często aktualizowane jak COUNT(*) zwrócony w pierwszym instrukcja nie jest równa drugiej instrukcji ... może to spowodować wyświetlenie komunikatu o błędzie "Nie znaleziono lub nie zmieniono wiersza".

1

(PS Wiem, że mówisz MsSQL jednak)

Nie jestem DBA ale count (*) w MySQL jest prawdziwym hitem wydajność. Po prostu zmiana tego w celu zliczenia (ID) naprawdę poprawia prędkość.

Natknąłem się na to, gdy pytałem o tabelę z bardzo dużymi danymi GLOB (Obrazy). Narzędzie do wysyłania zapytań około 15 sekund, aby załadować. Zmiana zapytania do zliczenia (id) zmniejszyła zapytanie do 0.02. Wciąż trochę powolny, ale o wiele lepiej.

Myślę, że właśnie to robi DBA. Zauważyłem wtedy, że podczas debugowania Linq'a stwierdzenie, które się liczy, zajmuje bardzo długi czas (1 sekundę), aby przejść do następnego stwierdzenia.

oparciu o moim odkryciu, muszę zgodzić się z conserns DBA za ...