2012-09-07 2 views
7

내 응용 프로그램에서 JPA를 사용하여 Hibernate를 사용하고 있으며 최대 절전 모드가 내 로그 파일에 많은 조인을 포함하는 흥미로운 SQL 쿼리를 생성한다는 것을 알았습니다. 응용 프로그램에는 현재 많은 사용자가 없기 때문에 최대 절전 모드로 생성되는 쿼리 중 일부는 데이터베이스 크기가 커질 때 문제가 발생할 것이라고 걱정됩니다.SQL 쿼리 결과의 결과는 데이터베이스의 크기에 따라 달라 집니까?

나는 생성 된 쿼리 계획을보기 위해 EXPLAIN 명령을 통해 최대 절전 모드로 생성 된 일부 SQL 쿼리를 실행했다.

  1. 데이터베이스의 크기에 따라 EXPLAIN의 결과가 달라 집니까? 데이터베이스가 커질 때 쿼리 계획자는 동일한 SQL 쿼리에 대해 다른 계획을 생성합니까?

  2. 최대 절전 모드에서 생성 된 SQL 쿼리에 대한 SQL 쿼리 계획을 개발/배포주기의 어느 시점에서 검토해야합니까? EXPLAIN을 사용할 적절한시기는 언제입니까?

  3. 데이터베이스가 너무 작아서 0.5 초 미만의 복잡한보기가 실행되는 것과 상관없이 모든 쿼리가 문제가 될 때 어떻게 결과를 확인할 수 있습니까?

내 응용 프로그램의 데이터베이스로 Postgres 9.1을 사용하고 있지만 위의 질문에 대한 일반적인 대답에 관심이 있습니다.

+3

스마트 데이터베이스는 * 통계 *를 사용하여 계획을 작성하는 방법에 대해 교육 된 추측을하도록 도와줍니다. 이러한 * 통계 *는 새로운 데이터로 인해 시간이 지남에 따라 변경 될 수 있습니다. 정확한 범위, 수집, 힌트 등은 매우 데이터베이스 별입니다. 그러나 이것은 [지금 당장 걱정할 사항이 아닙니다] 깨끗한 모델을 만드는 데 집중하십시오. –

+0

@pst 그래서 데이터베이스가 아직 작을 때 설명하는 것이 무의미하다는 것을 의미합니다. – ams

+2

곧 릴리스 될 예정인 9.2보다 오래된 PostgreSQL 버전의 경우, 명령문을'PREPARE'하고 Hibernate가 명령문을 실행하는 방법과 일치하도록'EXPLAIN EXECUTE'해야합니다. 준비된 문과 준비되지 않은 문에서 쿼리 계획은 9.1 이하에서 다를 수 있습니다. –

답변

4

1은 데이터베이스의 크기에 따라 EXPLAIN의 출력 캐시 크기를 초과 빠른 속도로 성능 저하 등을 볼 수 ? 데이터베이스가 커질 때 쿼리 계획자는 동일한 SQL 쿼리에 대해 다른 계획을 생성합니까?

모두 데이터 및 통계 데이터에 따라 다릅니다. 누군가 통계 분석을 잊어 버렸거나 auto_vacuum (분석 포함)을 해제했을 때 통계가 부족하기 때문에 많은 성능 문제가 발생합니다.

2 최대 절전 모드에서 생성 된 SQL 쿼리에 대한 SQL 쿼리 계획을 검토해야합니까? 언제 EXPLAIN을 사용할 적절한시기입니까?

하이버 네이트는 단순한 조인이라하더라도 데이터베이스에 많은 양의 쿼리를 보내는 버릇이있다. 네 querylog 켜고, 그 하나에 주시하십시오. 나중에 로그에서 모든 쿼리에 대해 자동 설명을 실행할 수 있습니다. 의 출력은 쿼리가 문제가 될 수 있는지를 확인하는 데 사용할 수 설명 할 수있는 방법

3, 데이터베이스가 너무 작아서 그 모든 쿼리 아무리 복잡한 찾고 실행 0.5 초 아래에서?

아니요, 데이터에 따라 다르기 때문입니다. 사용자의 95 %가 남성 인 경우 남성을 검색 할 때 성별에 대한 색인이 사용되지 않습니다. 당신이 여성을 찾고있을 때, 그 색인은 의미가 있으며 사용될 것입니다. 성별 = 여성이있는 레코드의 기능적 인덱스는 더 좋습니다. 인덱스에서 이익을 얻지 못하는 것을 인덱스하는 것은 쓸모 없으며 인덱스는 훨씬 작습니다.

인덱스 사용을 예측할 수있는 유일한 방법은 일부 인덱스를 사용할 수 있음을 나타내는 set enable_seqscan = off;으로 테스트하는 것뿐입니다.

+0

s/기능 색인/부분 색인/g? –

+0

Frank는 평소와 같이 죽었고, @ams는 모든 쿼리가 인덱스의 이점을 얻거나 사용해야한다고 생각하지 않습니다. 필터없이 두 개의 중소 규모 테이블을 조인 할 경우 seqscan과 mergejoin이 최상의 계획 일 수 있습니다. –

+1

물론 명령문이 서버 측에서 * prepared *이면 각 실행에 사용 된 인수를 기반으로하는 * generic * 계획을 사용해야합니다. 설명 된대로 젠더 예제 최적화에 문제가있을 수 있습니다. PostgreSQL JDBC 드라이버의'prepareThreshold' 옵션을보십시오. – kgrittn

5

실제로, @ams는 귀하의 의견에 있습니다. 일반적으로 소량의 데이터로 설명을 사용하는 것은 무의미합니다.

테이블에 10 개의 행만있는 경우 한 페이지에 모두 포함될 가능성이 높으며 한 행을 모두 10 개 읽으려면 (대략) 동일한 비용이 필요합니다. 먼저 인덱스로 이동 한 다음 페이지를 가져 오는 것이 제비 뽑기를 읽고 당신이 원하지 않는 것을 무시합니다. PostgreSQL의 플래너는 인덱스 읽기, 테이블 읽기, 디스크 접근과 캐시 접근, 정렬 등과 ​​같은 것들을 위해 configured costs을 가지고 있습니다. 테이블의 크기 (대략적인 크기)와 distribution of values에 따라 크기를 정합니다. 그것이하지 않는 것은 (보류중인 9.2 릴리스에서) 크로스 - 컬럼 또는 크로스 - 테이블 상관 관계에 대한 설명이다. 또한 플래너의 선택 사항을 무시할 수있는 수동 힌트도 제공하지 않습니다 (MS-SQL 또는 Oracle과 달리).

각 RDBMS의 플래너는 각기 다른 강점과 약점을 가지고 있지만 MySQL이 가장 약한 버전이라고 말할 수 있습니다.

그래서 100 명의 동시 사용자와 수십억 개의 행을 사용하여 시스템이 어떻게 작동하는지 알고 싶다면 테스트 데이터를 생성하고 그 중 상당 부분을로드해야합니다. 더 나쁜 것은 대략 동일한 가치 분포를 원할 것입니다. 대부분의 고객이 인보이스 약 10 개를 가지고 있지만 1,000 개가 몇 개이면 테스트 데이터에 반영해야합니다. 여러 RDBMS에서 성능을 유지해야하는 경우 모든 RDBMS에서 테스트를 반복하십시오.

이것은 시스템의 전체 성능과는 별개로 서버의 크기와 기능에 따라 다릅니다. 시스템은 부하의 꾸준한 증가에 대처할 수 있으며, 갑자기 당신은

HTH

관련 문제