2011-09-07 18 views
6

Soy un fanático de ORM - Asignación relacional de objetos y lo he usado con Rails durante el último año y medio. Antes de eso, uso para escribir consultas crudas usando JDBC y hago que la base de datos haga el trabajo pesado a través de los procedimientos almacenados. Con ORM, al principio estaba feliz de hacer cosas como coach.manager y manager.coaches que eran muy simples y fáciles de leer.Desventajas del mapeo relacional de objetos

Pero a medida que pasaba el tiempo, se multiplicaron las asociaciones y terminé haciendo a.b.c.d, que fueron preguntas de disparos en todas las direcciones, detrás de las escenas. Con los rieles y el rubí, el recolector de basura se volvió loco y tomó un tiempo insensato para cargar una página muy compleja que involucra datos relativamente menores. Tuve que reemplazar este código de estilo ORM por un simple procedimiento almacenado y el resultado que vi fue enorme. Una página que tardó 50 segundos en cargarse ahora solo tarda 2 segundos.

Con esta gran diferencia, ¿debo seguir usando ORM? Está muy claro que tiene gastos indirectos severos en comparación con una consulta sin formato.

En general, ¿cuáles son los inconvenientes generales de utilizar un marco ORM como Hibernate, ActiveRecord?

+0

¿Estás usando la recuperación perezosa? Básicamente 'ORM' carga tanto como usted lo dice ... –

+0

@Petar Minichev: Bueno, no puedo decir una respuesta directa a eso ya que estoy haciendo todo tipo de búsquedas que ORM me permite. Hay un poco de intercambio en todos lados – bragboy

Respuesta

5

Creo que ya ha identificado la mayor compensación asociada con el software ORM. Cada vez que agregue una nueva capa de abstracción que intente proporcionar una implementación generalizada de algo que solía hacer a mano, habrá una cierta pérdida de rendimiento/eficiencia.

Como ha señalado, atravesar relaciones múltiples como a.b.c.d puede ser ineficiente, porque la mayoría del software ORM hará una consulta de base de datos independiente para cada . en el camino. Pero no estoy seguro de que eso signifique que debes eliminar el ORM por completo. La mayoría de las soluciones ORM (o al menos, ciertamente Hibernate) le permiten especificar consultas personalizadas donde puede recuperar exactamente lo que desea en una sola operación de base de datos. Esto debería ser tan rápido como su SQL dedicado.

En realidad, el problema consiste en comprender cómo funciona la capa ORM entre bastidores, y darse cuenta de que algo como a.b.c.d es simple de escribir, lo que hace que la capa ORM no se evalúe. Como regla general, siempre uso el enfoque más simple posible para comenzar, y luego escribo consultas optimizadas en áreas donde tiene sentido/donde es obvio que el enfoque simple no se escalará.

12

Un ORM es solo una herramienta. Si no lo usa correctamente, obtendrá malos resultados.

Nada le impide utilizar consultas dedicadas de HQL/criterios, con fetch joins o proyecciones, para devolver la información que su página debe mostrar en tan pocas consultas como sea posible. Esto llevará más o menos el mismo tiempo que las consultas SQL dedicadas.

Pero, por supuesto, si obtiene todo por ID y navega por sus objetos sin darse cuenta de cuántas consultas genera, dará lugar a largos tiempos de carga. La clave es saber exactamente qué hace el ORM detrás de la escena, y decidir si es apropiado o si se debe adoptar otra estrategia.

3

Yo diría que se debe usar la herramienta adecuada para las diferentes tareas.

P. ej., Para operaciones CRUD, marcos de ORM como Hibernate pueden acelerar el desarrollo y funcionarán lo suficientemente bien. A veces es necesario hacer algunos ajustes necesarios para lograr un rendimiento aceptable. No estoy seguro, su tarea (lo que tomó 50 segundos con Hibernate) no se pudo hacer correctamente con Hibernate, porque no nos proporcionó los detalles.

Por otro lado, por ejemplo, las operaciones masivas que involucran cientos de miles de registros no son el tipo de tarea que esperaría que hiciera Hibernate sin una importante penalización de rendimiento.

1

Estoy con Petar por sus comentarios sobre la recuperación perezosa. Supongamos que tiene una tabla html llena campos del objeto a.b.c.d. Puede encontrar su marco de trabajo de forma circular: tropezar con la base de datos miles de veces (posiblemente muchas más). La desventaja de ORM en este caso es que tiene que leer la documentación a fondo. La mayoría de los marcos admiten deshabilitar la recuperación diferida y muchos incluso admiten la adición de su propia lógica de procesamiento para vincular el conjunto de datos.

La salida es que casi cualquier ORM es casi indudablemente mejor que cualquier cosa que va a escribir usted mismo. Te verás agobiado por mantener enormes bibliotecas de texto repetitivo o peor escribiendo el mismo código una y otra vez.

2

Como ya se mencionó, ORM es solo una herramienta y se puede usar bien o mal.

Uno de los problemas de rendimiento más típicos en ORM es 1 + N problema de consultas. Se produce al cargar objetos adicionales para cada uno de los objetos de la lista. Esto se debe a la búsqueda ansiosa de entidades de relación 1 a n para cada elemento en la lista, el trato consiste en utilizar consultas HQL, especificar campos en proyección o marcar la obtención de relaciones 1 a n a la pereza.

En cualquier momento, debe saber exactamente qué está haciendo el ORM para lograr un buen rendimiento. No entender qué operaciones se realizan en segundo plano es una forma de desastre (código lento, con errores y difícil de analizar debido a problemas de escritura innecesarios y escritos erróneamente).

0

Actualmente estamos investigando para cambiar de nuestra propia capa de almacén de datos con la separación limpia de objetos de transferencia y objetos de acceso a datos a JPA. Usamos un generador para crear los TO, los DAO y el SQL DDL, así como algunos documentos en formato de libro de doc. Con esto, todo nuestro material de la documentación, la estructura de la base de datos y las clases Java generadas siempre están sincronizadas con una buena documentación de la base de datos.

Lo que hemos descubierto hasta ahora mediante el uso de JPA:

  1. referencias de clave externa no se pueden utilizar para las importaciones, algunas especiales consultas y así sucesivamente, ya que no deben ser localizados en una entidad gestionada. JPA solo permite la clase objetivo allí.
  2. El acceso a un alcance de sesión de usuario es difícil o imposible. Nosotros todavía no tenemos idea de cómo obtener la identificación de los usuarios en la columna 'userWhoLastMadeAnUpdate' en algún método PrePersist.
  3. Algo que se espera que sea bastante fácil con un ORM, es decir, "asignación de clase " no funciona en absoluto. Estamos utilizando HalDateTime (http://sourceforge.net/projects/haldatetime/) internamente. Especialmente en el cliente. Mapearlo directamente con JPA no es , aunque HalDateTime lo admite. Debido a las restricciones de JPA , tenemos que usar dos campos en la entidad.
  4. JPA utiliza un archivo XML para describir la asignación. De modo que tiene que buscar al menos en dos archivos para comprender incluso la relación entre la clase Java y la base de datos. Y el archivo XML se convierte en enorme para grandes aplicaciones.
  5. Alternativamente, los ORM proporcionan anotaciones en la propia clase de Java. Así que es más fácil de aprender y entender la relación.Pero obliga a a ver todas las cosas de la base de datos en la capa del cliente (que rompe por completo una capa adecuada).
  6. Tendrá que limitarse a mantenerse lo más cerca posible de una estructura de base de datos limpia como sea posible. De lo contrario, seguro terminarán con un lío de consultas y declaraciones por parte de ORM.
  7. Utilice un ORM que proporcione un lenguaje de consulta que se acerque a SQL (JPA parece bastante aceptable aquí). Un lenguaje inducido por ORM hace que el soporte de una aplicación grande sea realmente costoso.
Cuestiones relacionadas