2011-08-02 3 views
1

테스트 케이스 :H2 최적화 SELECT 문/종료 조각 모음

drop table master; 
create table master(id int primary key, fk1 int, fk2 int, fk3 int, dataS varchar(255), data1 int, data2 int, data3 int, data4 int,data5 int,data6 int,data7 int,data8 int,data9 int,b1 boolean,b2 boolean,b3 boolean,b4 boolean,b5 boolean,b6 boolean,b7 boolean,b8 boolean,b9 boolean,b10 boolean,b11 boolean,b12 boolean,b13 boolean,b14 boolean,b15 boolean,b16 boolean,b17 boolean,b18 boolean,b19 boolean,b20 boolean,b21 boolean,b22 boolean,b23 boolean,b24 boolean,b25 boolean,b26 boolean,b27 boolean,b28 boolean,b29 boolean,b30 boolean,b31 boolean,b32 boolean,b33 boolean,b34 boolean,b35 boolean,b36 boolean,b37 boolean,b38 boolean,b39 boolean,b40 boolean,b41 boolean,b42 boolean,b43 boolean,b44 boolean,b45 boolean,b46 boolean,b47 boolean,b48 boolean,b49 boolean,b50 boolean); 

create index idx_comp on master(fk1,fk2,fk3); 
@loop 5000000 insert into master values(?, mod(?,100), mod(?,5), ?,'Hello World Hello World Hello World',?, ?, ?,?, ?, ?, ?, ?, ?,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,false,false,false,true); 

1. select 문 다음은 30초이 소요됩니다. 응답 시간을 최적화하는 방법이 있습니까?

SELECT count(*), SUM(CONVERT(b1,INT)) ,SUM(CONVERT(b2,INT)),SUM(CONVERT(b3,INT)),SUM(CONVERT(b4,INT)),SUM(CONVERT(b5,INT)),SUM(CONVERT(b6,INT)),SUM(CONVERT(b7,INT)),SUM(CONVERT(b8,INT)),SUM(CONVERT(b9,INT)),SUM(CONVERT(b10,INT)),SUM(CONVERT(b11,INT)),SUM(CONVERT(b12,INT)),SUM(CONVERT(b13,INT)),SUM(CONVERT(b14,INT)),SUM(CONVERT(b15,INT)),SUM(CONVERT(b16,INT)) 
FROM master 
WHERE fk1=53 AND fk2=3 

2. 종료 조각 모음을 시도했습니다. 그러나이 성명서는 내 시험 경우에 약 40 분이 걸렸다. 셧다운 종료 후 선택에는 최대 15 초가 소요됩니다. 문을 다시 실행하면 1 초 이내에 완료됩니다. 서버를 중지하고 시작하더라도 명령문은 약 1 초가 걸립니다. H2에 지속적인 캐시가 있습니까?

인프라 : 웹 브라우저 < -> H2 콘솔 서버 < -> H2 DB : 1.3.158

+0

쿼리가 몇 행입니까? 50000 (확실하지 않음) 인 것 같습니다. COUNT (*) SUM을 선택 –

+0

(CONVERT (B1, INTEGER)) SUM ((B16을 CONVERT, INTEGER)) PUBLIC.MASTER FROM /* PUBLIC.IDX_COMP : FK1 = 53 AND FK2 = 3 */ /* scanCount : 50,001 */ (FK1 = 53) AND (FK2가 = 3) /* 총 : 55,199 MASTER.IDX_COMP 읽기 : 481 (0 %) 하는 판독 MASTER.MASTER_DATA : 54718 (99 %) */ (1 Datensatz, 27368 ms) – Peter

답변

2

프로파일 러 출력에 따르면 주요 문제 (93 %)는 디스크에서 읽는 것입니다.

@prof_start; 
SELECT ... FROM master WHERE fk1=53 AND fk2=3; 
@prof_stop; 

을 얻은 : 나는 H2 콘솔이 실행이 디스크 (2킬로바이트 각 페이지 110 MB)에서 55'000 페이지 위에 읽는 것

Profiler: top 3 stack trace(s) of 48039 ms [build-158]: 
4084/4376 (93%): 
at java.io.RandomAccessFile.readBytes(Native Method) 
at java.io.RandomAccessFile.read(RandomAccessFile.java:338) 
at java.io.RandomAccessFile.readFully(RandomAccessFile.java:397) 
at org.h2.store.FileStore.readFully(FileStore.java:285) 
at org.h2.store.PageStore.readPage(PageStore.java:1253) 
at org.h2.store.PageStore.getPage(PageStore.java:707) 
at org.h2.index.PageDataIndex.getPage(PageDataIndex.java:225) 
at org.h2.index.PageDataNode.getRowWithKey(PageDataNode.java:269) 
at org.h2.index.PageDataNode.getRowWithKey(PageDataNode.java:270) 

따르면 EXPLAIN ANALYZE SELECT에이 쿼리에 대해 . 나는 다른 데이터베이스가 그러한 쿼리를 어떻게 수행하는지 잘 모르겠습니다. 하지만 가능한 적은 데이터를 읽도록 쿼리를 변경해야합니다 같아요.

+1

테스트 케이스에서 셧다운이 느려지는 이유는 무엇입니까? 왜 서버를 다시 시작한 후 느린 진술이 빠릅니까? – Peter

1

H2는 이미 완료 데이터 유형 변환이있는 임시 테이블/뷰를 가질 수 있습니까? 메인 테이블에서 업데이트를하는 것이 가끔씩 (야간에 한 번) 가능하다면 이미 완료된 변환으로 처리 할 수있는 많은 권한이 있습니다.

가능하지 않은 경우 각 "b"열에 하나씩 여러 개의 하위 선택을 할 수 있습니다. 여기서 b # = 1을 가져옵니다. 그런 다음 SUM 대신 COUNT를 수행하십시오. 잘. 예를 들어 : 그 정확한 구문이 프로그램에서 작동하지만, 희망 일반적인 SQL 아이디어로는 바른 길에 당신을 얻는 경우에

SELECT (count1+count2) AS Count, 
(SELECT COUNT(*) FROM master WHERE fk1=53 AND fk2=3 AND b1=1) AS count1 
(SELECT COUNT(*) FROM master WHERE fk1=53 AND fk2=3 AND b2=1) AS count2 

잘 모르겠어요.

+0

나는 첫 번째 su를 따랐다. 내 테스트 케이스에서 부울을 tinyint로 대체하여 ggestion. select 문은 SELECT count (*), SUM (b1) ... SUM (b16) 처럼 보입니다. – Peter

+0

심지어 SELECT COUNT (*)에서 마스터 fK1 = 93 및 fk2 = 3 및 b2 = 1까지 15 초가 소요됩니다. 더 큰 (tinyint> 부울) 데이터베이스는 응답 시간이 나 빠집니다. – Peter

+0

그건 50k 행 합계가 너무 작아서 (위의 주석을 올바르게 이해하면 하위 쿼리 당 50k 또는 총 행 수가 50k가됩니까?).3 열 인덱스가 있다는 사실은 그것에 기여할 수 있습니다. 세 가지 모두를 하나의 색인으로 색인하는 이유는 무엇입니까? 가장 까다로운 쿼리에 fk3이 없기 때문에 인덱싱을 방해하는 이유가 궁금합니다. 복합 인덱스로 추가하는 것이 훨씬 적습니다. – roberttdev