2011-09-07 3 views
6

저는 ORM - 객체 관계 매핑의 팬이며 지난 1 년 반 동안 레일즈에서 사용 해왔습니다. 이전에는 JDBC를 사용하여 원시 쿼리를 작성하고 Database가 Stored Procedures를 통해 무거운 작업을 수행하는 데 사용합니다. ORM을 사용하면 처음에는 coach.managermanager.coaches과 같은 것들을 매우 기쁘게 읽었으며 매우 간단하고 읽기가 쉬웠습니다.객체 관계 매핑의 단점

하지만 시간이지나면서 수많은 연관이 많아지면서 a.b.c.d은 모든면에서 모든 방향으로 쿼리를 실행하고있었습니다. 레일과 루비로 가비지 컬렉터는 열악한 데이터를 필요로하는 매우 복잡한 페이지를로드하는 미친 시간을 보냈습니다. 이 ORM 스타일 코드를 간단한 Stored 프로 시저로 대체해야했고 결과는 엄청났습니다. 페이지를로드하는 데 50 초가 걸리던 데는 2 초 밖에 걸리지 않습니다.

이 큰 차이점과 함께 ORM을 계속 사용해야합니까? 원시 쿼리와 비교할 때 심각한 오버 헤드가 있다는 것이 확실합니다.

일반적으로 Hibernate, ActiveRecord와 같은 ORM 프레임 워크를 사용하는 일반적인 함의는 무엇입니까?

+0

게으른 가져 오기를 사용하고 있습니까? 기본적으로'ORM'은 당신이 말한만큼 로딩합니다 ... –

+0

@Petar Minichev : ORM이 모든 종류의 fetchings을 수행하고 있기 때문에 그 것에 대한 직접적인 대답은 말할 수 없습니다. 어디에서나 약간의 트레이드 오프가 있습니다. – bragboy

답변

5

여러분은 이미 ORM 소프트웨어와 관련된 주요 장단점을 확인했다고 생각합니다. 수작업으로 수행했던 작업의 일반화 된 구현을 제공하려는 새로운 추상화 계층을 추가 할 때마다 성능/효율성이 다소 저하 될 것입니다.

a.b.c.d과 같은 여러 관계를 탐색하는 것은 비효율적 일 수 있습니다. 대부분의 ORM 소프트웨어는 각 .에 대해 독립적 인 데이터베이스 쿼리를 수행하기 때문입니다. 그러나 이것이 ORM을 완전히 제거해야 함을 의미하지는 않습니다. 대부분의 ORM 솔루션 (또는 적어도 확실하게 Hibernate)을 사용하면 단일 데이터베이스 작업에서 원하는 것을 정확하게 되돌릴 수있는 사용자 정의 쿼리를 지정할 수 있습니다. 이것은 전용 SQL만큼 빠르다.

실제로 문제는 ORM 계층이 장면 뒤에서 어떻게 작동 하는지를 이해하고 a.b.c.d과 같은 것이 쓰기 쉽지만 ORM 계층이 평가할 때 수행하게하는 것은 무엇인지 깨닫는 것입니다. 일반적으로 나는 항상 가장 간단한 접근법을 사용하여 시작하고, 그것이 의미있는 영역에서/최적화 된 쿼리를 작성합니다. 간단한 접근법이 확장되지 않는다는 것이 명백합니다.

12

ORM은 하나의 도구 일뿐입니다. 올바르게 사용하지 않으면 나쁜 결과를 초래할 수 있습니다.

페치 조인 또는 투영과 함께 전용 HQL/criteria 쿼리를 사용하여 페이지가 가능한 한 적은 수의 쿼리로 표시해야하는 정보를 반환하지 않습니다. 전용 SQL 쿼리와 거의 같은 시간이 소요됩니다.

물론 ID로 모든 것을 얻고 생성 한 쿼리 수를 인식하지 않고 개체를 탐색하면로드 시간이 길어집니다. 핵심은 ORM이 현장에서 무엇을하는지 정확히 알고 적절한 지 또는 다른 전략을 채택해야하는지 결정하는 것입니다.

3

다른 작업에 적절한 도구를 사용해야합니다.

예를 들어, CRUD 작업의 경우 Hibernate와 같은 ORM 프레임 워크가 개발 속도를 높이고 성능이 충분할 수 있습니다. 때로는 수용 가능한 성능을 달성하기 위해 몇 가지 조정을해야합니다. 나도 잘 모르겠다. Hibernate에서 50 초가 걸린 작업은 Hibernate에서 제대로 수행되지 않았다. 왜냐하면 당신이 우리에게 세부 사항을 제공하지 않았기 때문이다.

반면에, 수십만 개의 레코드를 포함하는 일괄 작업은 Hibernate가 상당한 성능 저하없이 수행 할 것으로 예상되는 작업 유형이 아닙니다.

1

나는 페치와 함께 게으른 페칭에 대한 의견을 갖고 있습니다. a.b.c.d 개체의 html 테이블 채우기 필드가 있다고 가정 해보십시오. 수천 번 (아마도 더 많은 것) 데이터베이스를 왕복하는 프레임 워크를 찾을 수 있습니다. 이 경우 ORM의 단점은 문서를 철저히 읽어야한다는 것입니다. 대부분의 프레임 워크는 지연 페칭을 사용하지 못하도록 지원하며 데이터 세트를 바인딩하기 위해 자체 프로세싱 로직을 추가하는 것을 지원합니다.

그물은 거의 모든 ORM이 당신이 쓰려고하는 것보다 거의 확실합니다. 당신은 보일러 판의 거대한 라이브러리를 유지하거나 동일한 코드를 계속해서 반복 작성하는 것에 매달려 있음을 알게 될 것입니다.

2

이미 언급했듯이 ORM은 도구 일 뿐이므로 좋은 결과 또는 나쁜 결과를 사용할 수 있습니다.

ORM의 가장 일반적인 성능 문제 중 하나는 1 + N 쿼리 문제입니다. 이는 각 오브젝트에 대한 추가 오브젝트를 목록에서로드하여 발생합니다. 이는 목록의 각 요소에 대해 1 대 n 관계 엔티티를 열심히 가져 오는 것으로 발생하며, 처리는 HQL 쿼리를 사용하거나, 프로젝션에서 필드를 지정하거나, 1 대 n 릴레이션을 lazy로 가져 오는 것으로 표시합니다.

언제든지 좋은 성능을 얻기 위해 ORM이 수행하는 작업을 정확히 알아야합니다. 어떤 작업이 백그라운드에서 수행되는지 이해하지 않으면 재난에 이르게됩니다 (불필요하고 잘못 작성된 해결 방법으로 인해 느리고 버그가 많으며 코드를 분석하기가 어렵습니다).

0

우리는 현재 전송 객체와 데이터 액세스 객체를 JPA로 완전히 분리하여 자체 데이터 저장소 계층에서 전환하는 방법을 조사 중입니다. 우리는 생성기를 사용하여 TO, DAO 및 SQL DDL을 docbook 형식의 설명서에서 만들었습니다. 문서, 데이터베이스 구조 및 생성 된 Java 클래스의 모든 것들을 통해 항상 데이터베이스 자체의 좋은 문서와 항상 동기화됩니다. 우리가 지금까지 JPA를 사용하여 발견 무엇

:

  1. 외래 키 참조가 수입에 사용할 수없는이 특별한 쿼리 등 그들은 관리 엔티티에 배치되지 않아야하기 때문이다. JPA는 대상 클래스 만 허용합니다.
  2. 일부 사용자 세션 범위에 액세스하는 것은 거의 불가능합니다. 우리는 여전히 일부 PrePersist 메서드에서 사용자 ID를 'userWhoLastMadeAnUpdate'열로 가져 오는 방법에 대한 단서가 없습니다.
  3. ORM에서 "클래스 매핑"이라는 매우 쉬운 작업이 예상됩니다. 내부적으로 HalDateTime (http://sourceforge.net/projects/haldatetime/)을 사용하고 있습니다. 특히 클라이언트에 있습니다. HalDateTime이 지원하지만 JPA로 직접 매핑하는 것은 가능하지 않습니다 ( ). JPA 제한 으로 인해 엔티티에서 두 개의 필드를 사용해야합니다.
  4. JPA는 하나의 XML 파일을 사용하여 매핑을 설명합니다. 그래서 적어도 두 파일을 봐야만 Java 클래스와 데이터베이스 사이의 관계가 이됩니다. 그리고 XML 파일은 대형 응용 프로그램에 대해 큰 이됩니다.
  5. ORM은 Java 클래스 자체에 주석을 제공합니다. 따라서 은 배우기 쉽고 관계를 이해하기 쉽습니다.그러나 은 클라이언트 계층에서 모든 데이터베이스 항목을 보도록합니다 ( 은 적절한 계층화를 완전히 중단합니다).
  6. 어쨌든 가능하면 깨끗한 데이터베이스 구조에 가깝게 머물러 있어야합니다. 그렇지 않으면 이 ORM에 의한 질의와 명령문의 엉망으로 끝날 것입니다.
  7. SQL 에 가까운 쿼리 언어를 제공하는 ORM을 사용하십시오 (JPA는 여기에서 상당히 허용됩니다). ORM 유도 언어 은 대형 응용 프로그램을 실제로 비싸게 지원합니다.