2010-02-12 28 views
6

Estoy usando la clase PagedList en mi aplicación web que muchos de ustedes podrían estar familiarizados si ha estado haciendo algo con ASP.NET MVC y LINQ to SQL. Se ha escrito en el blog por Rob Conery, y una encarnación similar se incluyó en cosas como Nerd Dinner, etc. Funciona de maravilla, pero mi DBA ha planteado preocupaciones sobre posibles problemas de rendimiento futuro.LINQ to SQL Pagination y COUNT (*)

Su tema es alrededor del SELECT COUNT (*) que obtiene emitido como resultado de esta línea:

TotalCount = source.Count(); 

Cualquier acción que ha paginado datos disparar una consulta adicional (como abajo) como consecuencia del IQueryable.Count() llamada al método:

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

¿hay una mejor manera de manejar esto? Consideré usar la propiedad Count de la clase PagedList para obtener el recuento de elementos, pero me di cuenta de que esto no funcionaría porque solo cuenta el número de elementos que se muestran actualmente (no el recuento total).

¿Cuánto impacto en el rendimiento causará esto a mi aplicación cuando hay una gran cantidad de datos en la base de datos?

Respuesta

8

iirc esto es parte de las estadísticas de índice y debe ser muy eficiente, debe pedirle a su DBA que corrobore sus inquietudes, en lugar de optimizarlo prematuramente.

+2

upvoted con tanta fuerza que rompió internet. ;) Si una consulta de conteo adicional va a reducir el rendimiento de su base de datos, tiene algunos problemas serios. – jfar

1

Algunas bases de datos (Oracle, Postgresql, SQL Server, creo) mantienen un registro de recuentos de filas en las tablas del sistema; aunque a veces solo son exactos hasta el punto en que las estadísticas fueron actualizadas por última vez (Oracle). Puede usar este enfoque si solo necesita una métrica bastante precisa pero no exacta.

¿Qué base de datos está usando, o eso varía?

+0

SQL Server 2005 –

2

En realidad, este es un problema bastante común con Linq.

Sí, las estadísticas de índice se utilizarán si la declaración fue solo SELECT COUNT(*) AS [value] FROM [dbo].[Products] AS [t0] pero el 99% de las veces también contendrá declaraciones WHERE.

Así que, básicamente, dos sentencias SQL se ejecutan:

  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

Empiezas problemas en la recepción si la tabla se actualiza a menudo como el COUNT(*) devuelto en la primera la declaración no es igual a la segunda declaración ... esto puede devolver un mensaje de error 'Fila no encontrada o cambiada'.

1

(PS Sé que usted está hablando de MsSQL sin embargo)

yo no soy DBA, pero la cuenta (*) en MySQL es un impacto en el rendimiento real. Simplemente cambiar esto a contar (ID) realmente mejora la velocidad.

Me encontré con esto cuando estaba consultando una tabla con datos GLOB (Imágenes) muy grandes. La herramienta de consulta tarda unos 15 segundos en cargarse. Cambiar la consulta para contar (id) redujo la consulta a 0.02. Todavía un poco lento, pero muchísimo mejor.

Creo que esto es lo que está recibiendo el DBA. Me he dado cuenta cuando depurar Linq la afirmación que cuenta toma un tiempo muy largo (1 segundo) para pasar a la siguiente declaración.

Con base en mi hallazgo Estoy de acuerdo con conserns del DBA ...