it-swarm-ko.tech

NHibernate의 성능을 향상시키는 가장 좋은 방법은 무엇입니까?

NHibernate를 ORM으로 사용하는 응용 프로그램이 있으며 때로는 데이터 액세스 방법으로 인해 성능 문제가 발생합니다. NHibernate의 성능을 향상시키기 위해 어떤 종류의 일을 할 수 있습니까? (답변 당 하나의 추천으로 제한하십시오)

61
Ray Vega

NHibernate로 겪을 수있는 첫 번째이자 가장 극적인 성능 문제는 모든 세션마다 새로운 세션 팩토리를 생성하는 것입니다. 각 애플리케이션 실행마다 하나의 세션 팩토리 인스턴스 만 작성해야하며 해당 세션에서 모든 세션을 작성해야합니다.

이 줄들과 함께 동일한 세션을 이해하는 한 계속 사용해야합니다. 이는 응용 프로그램마다 다르지만 대부분의 웹 응용 프로그램의 경우 요청 당 단일 세션이 권장됩니다. 세션을 자주 버려도 캐시의 이점을 얻지 못합니다. 지능적으로 세션 캐시를 사용하면 많은 수의 작업없이 선형 (또는 더 나쁜) 쿼리 수가있는 루틴을 상수로 변경할 수 있습니다.

마찬가지로 객체 참조를 게으르게로드하고 있는지 확인하는 것이 중요합니다. 그렇지 않은 경우 가장 간단한 쿼리조차도 전체 개체 그래프를로드 할 수 있습니다. 이를 수행하지 않는 특정 이유가 있지만 지연로드로 시작하고 필요에 따라 다시 전환하는 것이 좋습니다.

게으른 로딩과는 반대로 페치를 열망하게 만듭니다. 개체 계층 구조를 탐색하거나 컬렉션을 반복하는 동안 얼마나 많은 쿼리를 작성했는지 추적하기가 쉽지 않으며 기하 급수적 인 쿼리가 발생할 수 있습니다. FETCH JOIN을 사용하면 쿼리 단위로 더 빠른 페치를 수행 할 수 있습니다. 항상 조인을 가져 오는 특정 테이블 쌍이있는 경우와 같이 드문 상황에서는 해당 관계에 대해 지연로드를 해제하는 것이 좋습니다.

항상 그렇듯이 SQL 프로파일 러는 느리게 실행되거나 반복되는 쿼리를 찾는 좋은 방법입니다. 마지막 작업에서 페이지 요청 당 쿼리 수를 계산하는 개발 기능이있었습니다. 많은 수의 루틴에 대한 쿼리는 루틴이 NHibernate와 잘 작동하지 않음을 나타내는 가장 확실한 지표입니다. 루틴 또는 요청 당 쿼리 수가 양호 해 보인다면 아마도 데이터베이스 조정에 따른 것일 수 있습니다. 실행 계획과 데이터를 캐시에 저장하고 데이터를 올바르게 인덱싱하는 등의 메모리가 충분한 지 확인하십시오.

우리가 겪은 까다로운 작은 문제 중 하나는 SetParameterList ()입니다. 이 기능을 사용하면 매개 변수 목록을 쿼리에 쉽게 전달할 수 있습니다. NHibernate는 전달 된 각 항목에 대해 하나의 매개 변수를 작성하여이를 구현했습니다. 결과적으로 모든 매개 변수 수에 대해 다른 쿼리 계획이 작성됩니다. 우리의 실행 계획은 거의 항상 캐시에서 해제되었습니다. 또한 많은 매개 변수가 쿼리 속도를 크게 저하시킬 수 있습니다. 우리는 NHibernate의 커스텀 해킹을 통해 단일 매개 변수로 항목을 구분 된 목록으로 보냈습니다. 이 목록은 해킹이 쿼리의 IN 절에 자동으로 삽입 한 테이블 값 함수에 의해 SQL Server에서 분리되었습니다. 용도에 따라 이와 같은 다른 지뢰가있을 수 있습니다. SQL 프로파일 러는 가장 좋은 방법입니다.

53
Chuck

NHibernate의 SessionFactory는 고가의 작업이므로 메모리에 SessionFactory의 인스턴스가 하나만 있도록 싱글 톤을 만드는 것이 좋은 전략이다 :

   public class NHibernateSessionManager
    {
        private readonly ISessionFactory _sessionFactory;

        public static readonly NHibernateSessionManager Instance = new NHibernateSessionManager();

        private NHibernateSessionManager()
        {
            if (_sessionFactory == null)
            {
                System.Diagnostics.Debug.WriteLine("Factory was null - creating one");
                _sessionFactory = (new Configuration().Configure().BuildSessionFactory());
            }
        }

        public ISession GetSession()
        {
            return _sessionFactory.OpenSession();
        }

        public void Initialize()
        {
            ISession disposeMe = Instance.GetSession();
        }
    }

그런 다음 Global.Asax Application_Startup에서 초기화 할 수 있습니다.

protected void Application_Start()
{
    NHibernateSessionManager.Instance.Initialize();
}
26
David P

느리게 수행되는 쿼리를 위해 지연로드에서 열성 페치로 전환 할시기를 인식하여 Select N + 1 problem 을 피하고 최소화하십시오.

11
Ray Vega

NH Prof ( http://nhprof.com/ )는 유망한 것으로 보이며 ORM 프레임 워크 사용을 평가할 수 있습니다. NHibernate를 시작하기에 좋은 출발점이 될 수 있습니다.

10
MatthieuGD

현재보고있는 성능 문제의 종류에 대한 구체적인 설명 없이는 일반화 만 제공 할 수 있습니다. 내 경험상 대부분의 데이터베이스 쿼리 성능 문제는 적절한 지수가 부족하여 발생합니다. 따라서 첫 번째 조치에 대한 제안은 인덱싱되지 않은 쿼리에 대한 쿼리 계획을 확인하는 것입니다.

4
Mike Monette

"답변 당 하나의 추천"만? 그런 다음 나는 이것을 위해 갈 것입니다 :

둘 이상의 병렬 대 다수의 연관을 통한 결합으로 인해 결합 중복 (AKA 직교 제품)을 피하십시오. Exists-subqueries, MultiQueries 또는 FetchMode "subselect"를 대신 사용하십시오.

최대 절전 성능 조정 팁

3
gnome26

NHibernate는 즉시 사용할 수있는 매우 빠른 SQL을 생성합니다. 나는 1 년 동안 그것을 사용해 왔으며 아직 SQL을 작성하지 않아도됩니다. 모든 성능 문제는 Normalization 및 인덱스 부족에서 비롯되었습니다.

가장 쉬운 해결 방법은 쿼리의 실행 계획을 검사하고 특히 외래 키 열에서 적절한 인덱스를 만드는 것입니다. Microsoft SQL Server를 사용하는 경우 "데이터베이스 엔진 튜닝 관리자"가이를 도와줍니다.

3
Eric Lathrop

답변을 하나의 옵션으로 만 제한 할 수 있습니까? 이 경우 NHibernate의 두 번째 수준 캐시 메커니즘을 구현하도록 선택합니다.

이런 식으로 매핑 파일의 각 개체에 대해 캐시 전략을 정의 할 수 있습니다. 두 번째 수준 캐시는 이미 검색된 개체를 메모리에 유지하므로 데이터베이스에 대한 또 다른 라운드 트립을 만들지 않습니다. 이것은 거대한 성능 향상 도구입니다.

목표는 응용 프로그램이 지속적으로 액세스하는 오브젝트를 정의하는 것입니다. 그 중에는 일반적인 설정 등이 있습니다.

Nhibernate 2 단계 캐시에 대한 많은 정보와이를 구현하는 방법이 있습니다.

행운을 빕니다 :)

1
Hace

프로파일 링은 첫 번째 단계 (간단한 시간 단위 테스트)를 통해 가장 큰 이득을 얻을 수있는 곳을 찾습니다.

콜렉션의 경우 발행 된 선택문 수를 줄이기 위해 배치 크기 설정을 고려하십시오. 자세한 내용은 섹션 성능 향상 을 참조하십시오.

1
Richard

아직 게으른 로딩을 사용하지 않는 경우 (적절하게) 시작하십시오. 필요하지 않은 컬렉션을 가져 오는 것은 모든 것을 낭비합니다.

장 성능 향상 이 방법과 다른 방법으로 성능을 향상시킵니다.

1
lotsoffreetime

캐싱, 캐싱, 캐싱-첫 번째 레벨 캐싱을 올바르게 사용하고 있습니까 [세션을 조기에 종료하거나 StatelessSession을 사용하여 첫 번째 레벨 캐싱을 우회]? 자주 변경되지 않는 값에 대해 간단한 2 차 캐시를 설정해야합니까? 자주 변경되지 않는 쿼리의 속도를 높이기 위해 쿼리 결과 세트를 캐시 할 수 있습니까?

[또한 구성-항목을 불변으로 설정할 수 있습니까? 필요한 정보 만 다시 가져 와서 원래 엔터티로 변환하도록 쿼리를 재구성 할 수 있습니까? 배트맨은 댐에 오기 전에 수수께끼를 막을 수 있습니까? 죄송합니다.]

1
Watson

많은 자유 시간이 말한 것.

"성능 향상"문서의 19 장을 읽으십시오.
NHibernate : http://nhibernate.info/doc/nhibernate-reference/performance.html
최대 절전 모드 : http://docs.jboss.org/hibernate/core/3.3/reference/en/html/performance.html

SQL 프로파일 러 (또는 사용중인 데이터베이스와 동등한 기능)를 사용하여 오래 실행되는 쿼리를 찾으십시오. 적절한 인덱스를 사용하여 해당 쿼리를 최적화하십시오.

응용 프로그램의 거의 모든 단일 페이지에서 사용되는 데이터베이스 호출의 경우 CreateMultiQuery를 사용하여 단일 데이터베이스 쿼리에서 여러 결과 집합을 반환합니다.

그리고 물론 캐시. 페이지/컨트롤에 대한 OutputCache 지시문. 데이터를위한 NHibernate 캐싱.

0
Axl