2010-01-28 15 views
9

Escuché mucho sobre los problemas de rendimiento sobre la carga diferida, sin importar si en NHibernate, Linq ....¿La carga lenta es realmente mala?

El problema es N + 1 selecciona. Por ejemplo, quiero todas las publicaciones y sus usuarios, en foreach I lazy Load Users, los necesito. Necesito uno para las publicaciones, más N para cada usuario.

Lazy Loading:

1 - select ....from post
N - select ....from user

El enfoque de "bueno" es hacer una combinación:

1 - select .....from post inner join user on post.UserId = user.Id

Pero al ver generó EF SQL, Me di cuenta de que se desperdicia una gran cantidad de datos. Imagine que todas las publicaciones son del mismo usuario. Inner Join traerá todas las columnas de usuarios para cada fila de publicaciones.

En rendimiento, ¿qué enfoque es el mejor?

+0

Esta es una buena pregunta: cómo elegir, pero creo que la respuesta dependerá en gran medida de los datos.Sin embargo, creo que te sorprendería que las consultas múltiples a menudo sean peores que "desperdiciar datos" al devolver más de lo que necesitas. En otras palabras, hay casos en los que la carga diferida es buena, pero sorprendentemente pocos en aplicaciones "típicas". –

+0

Su respuesta también depende de su ORM, porque en el EF, para usar su ejemplo, estas no son las dos únicas opciones. –

+0

@Craig Stuntz ¿Qué otras opciones? Estoy usando EF4 –

Respuesta

10

La carga lenta no es ni buena ni mala. Ver esto para una más amplia explicación:

When should one avoid using NHibernate's lazy-loading feature?

en, carga diferida en general es un buen comportamiento predeterminado de un ORM, sino como un usuario ORM tiene que ser consciente de cuándo invalidar los datos por defecto y la carga ansiosamente El perfil del rendimiento de su aplicación es la mejor manera de tomar decisiones sobre el uso de la carga diferida o de no usarla. Tenga cuidado de no gastar demasiado esfuerzo en la optimización prematura.

+1

+1 para un enchufe desvergonzado

+0

Creo que la regla general es que a los DBA no les gusta y los desarrolladores de aplicaciones web lo hacen :) –

1

No hay nada malo y bueno para la carga perezosa. Tiene que decidir si prefiere cargar recursos en tiempo de ejecución o tiempos de carga de la aplicación. Por ejemplo: el tiempo real generalmente usa un búfer para evitar asignar recursos en tiempo de ejecución. Eso es lo opuesto a la carga lenta y es beneficioso para el software Real Time.

La carga diferida es beneficiosa si tiene una aplicación de larga duración y no desea asignar recursos al inicio.

4

El problema con Lazy Loading es saber qué es y cuándo puede morderte. Debe saber cuántos viajes potenciales se podrían realizar en la base de datos y cómo solucionarlos. No veo LL como malo. Solo necesito ser consciente de las ramificaciones de esto.

4

La mayoría de mis aplicaciones implican un límite de servicio (servicio web, WCF, etc.) y en ese punto la carga diferida en el OR/M no tiene sentido, y la implementación de cargas perezosas en las entidades que se encuentran encima de su servicio es amable de una mala idea (las entidades ahora deben saber sobre el servicio).

0

Subproceso antiguo, pero la búsqueda lo subió, así que estoy agregando mis dos centavos. Además de tener que estar al tanto de posibles problemas de rendimiento, la cuestión de acceder a los campos después de que se haya eliminado un contexto de datos me impide utilizar LL ahora. Si devuelve una instancia de una entidad desde un método donde se creó y eliminó un contexto de datos, que es cómo están diseñados para ser utilizados, acceder a esos campos virtuales generará una excepción de excepción. Las soluciones a esto son incluir los campos en las consultas (es decir, .Incluir), nunca devolver las clases de entidad de su capa de datos/servicio, o mantener los contextos de datos vivos por mucho más tiempo. Incluir los campos es la mejor opción, y eso es igual de fácil sin la carga diferida habilitada.

Cuestiones relacionadas