SlideShare a Scribd company logo
1 of 18
Download to read offline
Database query tuning
(포털 서비스 응답 성능 개선)
2016년 03월 04일
(곽중선)
Technical document
2 / 18
1. 포털 성능 개선
1.1 작업 개요
모 언론사 사내 인트라넷 서비스의 응답 성능 개선 작업
포털 서비스의 응답 속도가 현저히 저하되어 사용자들의 업무에 지장을 초래하고 있으며, 이에 포털
서비스의 쿼리 성능을 분석하고 튜닝하였음.
1.2 개선 내용
1.2.1 최근 게시 목록
현행 쿼리
SELECT doc_bbsid, doc_subject, doc_yearmon, doc_number, doc_writer
FROM igt_bbs
WHERE doc_urgency='Y' and doc_regdate > dateadd(dd,-1,getdate())
AND resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate())
AND is_restrict not like 'Y' order by doc_seq desc, doc_subseq asc
문제점
order by 절로 인해서 임시 테이블(worktable)이 생성되며, 포털 서비스에 사용자 접속 수가 증가할 경
우 자원의 부족이 발생하고 응답속도가 떨어짐.
조치 사항 및 개선점
SELECT doc_bbsid, doc_subject, doc_yearmon, doc_number, doc_writer
FROM igt_bbs
WHERE doc_urgency='Y' and doc_regdate > dateadd(dd,-1,getdate())
AND resv_date <= getdate() AND is_restrict not like 'Y' order by
doc_regdate desc
order by 절을 개선하여 임시 테이블이 생성되지 않도록 하였고, 쿼리 실행 단계가 2단계에서 1단계
로 단축되었음. 또한, 불필요한 조건을 제거하여 쿼리를 단순화 시킴
1.2.2 공지 확인
현행 쿼리
SELECT ltrim(notice_info) a FROM igt_notice WHERE userlog_id='17140'
Technical document
3 / 18
문제점
사용자가 공지 알림을 확인하였는지 확인하는 쿼리. ltrim 함수가 쿼리에 포함되어 있으므로 쿼리 실
행 시 인덱스를 사용하지 못하고, 3천여건에 달하는 레코드를 전부 조회함
조치 사항 및 개선점
SELECT notice_info a FROM igt_notice WHERE userlog_id='17140'
if(ninfo == "") -> if(ninfo.indexOf("Y") == -1 )
쿼리 상에서 함수를 사용하지 않도록 변경하고, 자바 스크립트 소스를 수정함. 인덱스를 사용함으로
쿼리 성능이 개선되었음.
1.2.3 긴급 메일 알람
현행 쿼리
SELECT count(*) as cnt
FROM igt_mail_inbox a, igt_mail b
WHERE a.doc_yearmon = b.doc_yearmon AND a.doc_number =b.doc_number
AND a.receiver= [client_id] AND a.recv_date IS NULL AND a.send_reserve
<= [current_date]
AND b.doc_spec ='긴급'
문제점
사용자의 수신 메일 중 긴급 메일에 한정하여 수신 건수를 출력하도록 개선하였으나, 그룹웨어 테이
블 중에서 데이터 양이 매우 많은 전자우편 테이블 2가지를 조인(join)함으로써 성능 저하 발생.
임시 테이블(worktable)이 생성되지는 않지만, 데이터 건수가 많음으로 인해서 논리적 읽기 횟수가
90 정도로 상당히 높음. (포털의 여타 쿼리들의 평균 논리적 읽기 횟수는 4~5회)
조치 사항 및 개선점
메일 수신 건수를 출력하지 않도록 변경함.
1.3 차주 작업 계획
1.3.1 메일 긴급 개선 알림
임시로 제거한 메일 알람 기능을 복원.
메일 발송 시 긴급 메일인 경우, igt_mail_inbox(메일 수신 알람) 테이블에 기록함으로써 수신 측 포털
페이지에서 쿼리 시 조인(join)을 사용하지 않고 수신 확인토록 변경
Technical document
4 / 18
1.3.2 게시판 성능 개선
게시판 전반에 걸쳐 2차 프로젝트 이후 다음과 같은 변동으로 성능 저하 발생
 쿼리 복잡도가 증가
 페이지 당 출력 레코드 수 증가
 게시판 수 증가 (10배 가량)
이에 게시판 전반에 걸쳐 쿼리 수행 시 임시 테이블(worktable)이 발생하고, 출력 성능이 낮아짐.
1.3.3 포털 성능 개선
업무 공지 / 최근 소식 / 부서 공지
SELECT doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number,
doc_writer, doc_regdate , writer_deptname
from igt_bbs where doc_bbsid in ( '4200000', '4200000', '4200000e') and
doc_regdate > dateadd(dd,-3,getdate())
and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) and
is_restrict not like 'Y'
order by doc_regdate desc
게시판 쿼리가 복잡하여, 임시 테이블이 발생함. 인덱스 개선 혹은 쿼리 변경 등 검토 필요.
메일 수신 내역
select
a.doc_yearmon,a.doc_number,b.doc_subject,b.doc_writer,b.doc_writername,b
.doc_spec,b.doc_type,a.doc_open, a.folder_date as openedDate,
a.recv_name from igt_mail_docfolder a, igt_mail b
where a.doc_yearmon = b.doc_yearmon and a.doc_number = b.doc_number
and a.userlog_id = '17140' and a.is_display = 'Y'
and a.folder_id = 10 and a.doc_open = 'N'
order by a.send_date desc
메일 수신 내역 쿼리가 복잡하여, 임시 테이블이 발생함. 인덱스 개선 등 검토 필요.
2. 포털 성능 개선 2차
2.1 작업 개요
사내 포털 서비스의 응답 성능 개선 작업
포털 서비스 1차 응답 성능 개선 이후, 포털 게시판 성능개선
Technical document
5 / 18
2.2 포털 성능 개선
2.2.1 업무공지 (gwTable1.html)
현행 쿼리
select doc_bbsid, doc_subject, doc_writername, doc_yearmon,
doc_number, writer_deptname,
convert(varchar(10),doc_regdate,111) || ' ' ||
convert(varchar(5),doc_regdate,108) as doc_regdate ,doc_writer
from igt_bbs
where doc_regdate > dateadd(dd,-3,getdate()) and (doc_bbsid='102')
and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate())
and is_restrict not like 'Y' order by doc_regdate desc
문제점
convert 함수 사용으로 인해, worktable 발생.
조치 사항 및 개선점
select doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number,
writer_deptname, doc_regdate ,doc_writer
from igt_bbs (index idx_bbs2)
where doc_regdate > dateadd(dd,-3,getdate()) and (doc_bbsid='102') and
resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) and
is_restrict not like 'Y' order by doc_regdate desc
doc_regdate를 convert함수로 변환하지 않고 바로 읽어내면, 자바스크립트의 Date type으로 변환
(conversion) 된다. Date 타입 객체를 문자열로 변환하기 위해 자바스크립트의 date2str() 함수를
/Lib/groupware.js 파일에 추하였고, 결론적으로 worktable이 생성되지 않음. 또한, index hint를 적용하였
음.
아래는 groupware.js 파일에 추가된 date2str 함수 소스이다.
// Date 객체를 문자열로 변환 'YYYY/MM/DD HH24:MI'
function date2str( _date )
{
// 년도 추출
var strYear = _date.getYear();
// 월 추출
var nMonth = _date.getMonth() + 1;
var strMonth = '';
if( nMonth < 10 )
strMonth = '0' + nMonth;
Technical document
6 / 18
else
strMonth = '' + nMonth;
// 일자 추출
var nDate = _date.getDate();
var strDate = '';
if( nDate < 10 )
strDate = '0' + nDate;
else
strDate = '' + nDate;
// 시 추출
var nHour = _date.getHours() + 1;
var strHour = '';
if( nHour < 10 )
strHour = '0' + nHour;
else
strHour = '' + nHour;
// 분 추출
var nMin = _date.getMinutes() + 1;
var strMin = '';
if( nMin < 10 )
strMin = '0' + nMin;
else
strMin = '' + nMin;
return strYear + '/' + strMonth + '/' + strDate + ' ' + strHour +
':' + strMin;
}
date2str 사용 예제는 아래와 같다.
cursor = database.cursor(
"select doc_bbsid, doc_subject, doc_writername, doc_yearmon,
doc_number,writer_deptname, doc_regdate, doc_writer from igt_bbs (index
idx_bbs2) where doc_regdate > dateadd(dd,-3,"+now_date()+") and
(doc_bbsid='102') and resv_date <= "+now_date()+" and resv_date >
dateadd(dd,-30,"+now_date()+") and is_restrict not like 'Y' order by
doc_regdate desc" );
// 화면에 최대 5개까지 항목을 보여준다.
for( i=0; cursor.next() && i<5; i++ )
{
record_set1[lc] = cursor.doc_bbsid;
record_set2[lc] = cursor.doc_subject;
record_set3[lc] = cursor.doc_writername;
record_set4[lc] = cursor.doc_yearmon;
record_set5[lc] = cursor.doc_number;
record_set6[lc] = cur_dept.bbs_name;
Technical document
7 / 18
record_set7[lc] = cursor.doc_writer;
record_set8[lc] = date2str(cursor.doc_regdate);
record_set9[lc] = cursor.writer_deptname;
}
cursor.close();
2.2.2 본부 공지 (gwTable2.html)
현행 쿼리
SELECT doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number,
doc_writer,
convert(varchar(10),doc_regdate,111) || ' ' ||
convert(varchar(5),doc_regdate,108) as doc_regdate , writer_deptname
from igt_bbs where doc_bbsid in ( '4200000', '4200000', '4200000e') and
doc_regdate > dateadd(dd,-3,getdate())
and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) and
is_restrict not like 'Y'
order by doc_regdate desc
문제점
convert 함수 사용 및 doc_bbsid 컬럼에 대한 OR 조건(in 절)으로 인해 worktable 발생.
조치 사항 및 개선점
SELECT doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number,
doc_writer, doc_regdate , writer_deptname
from igt_bbs (index idx_bbs2)
where doc_regdate > dateadd(dd,-3,getdate())
and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) and
is_restrict not like 'Y'
order by doc_regdate desc
doc_regdate를 읽어내고, Date 타입 객체를 date2str 함수를 이용해 문자열로 변환함에 따라 worktable
이 생성되지 않음. 인덱스 힌트 사용
2.2.3 최근 게시 (gwTable4.html)
현행 쿼리
select doc_writername, doc_bbsid, doc_yearmon, doc_number, doc_subject,
Technical document
8 / 18
doc_writer, convert(varchar(10),doc_regdate,111) || ' ' ||
convert(varchar(5),doc_regdate,108) as doc_regdate, writer_deptname
from igt_bbs
where doc_regdate > dateadd(dd,-3,getdate()) and doc_bbsid in
(select bbs_id from igt_bbs_env where userlog_id='17140')
and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate())
and is_restrict not like 'Y' order by doc_regdate desc
문제점
convert 함수 사용으로 인해 worktable 발생.
조치 사항 및 개선점
select doc_writername, doc_bbsid, doc_yearmon, doc_number, doc_subject,
doc_writer, doc_regdate
doc_regdate, writer_deptname from igt_bbs (index idx_bbs2)
where doc_regdate > dateadd(dd,-3,getdate()) and doc_bbsid in
(select bbs_id from igt_bbs_env where userlog_id='17140')
and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate())
and is_restrict not like 'Y' order by doc_regdate desc
doc_regdate를 읽어내고, Date 타입 객체를 date2str 함수를 이용해 문자열로 변환함에 따라 worktable
이 생성되지 않음. 인덱스 힌트 사용
2.2.4 긴급 메일 알람
현행 쿼리
SELECT count(*) as cnt FROM igt_mail_inbox a, igt_mail b
WHERE a.doc_yearmon = b.doc_yearmon AND a.doc_number =b.doc_number
AND a.receiver= [client_id] AND a.recv_date IS NULL AND a.send_reserve
<= [current_date] AND b.doc_spec ='긴급'
문제점
사용자의 수신 메일 중 긴급 메일에 한정하여 수신 건수를 출력하도록 개선하였으나, 그룹웨어 테이
블 중에서 데이터 양이 매우 많은 전자우편 테이블 2가지를 조인(join)함으로써 성능 저하 발생.
임시 테이블(worktable)이 생성되지는 않지만, 데이터 건수가 많음으로 인해서 논리적 읽기 횟수가
90 정도로 상당히 높음. (포털의 여타 쿼리들의 평균 논리적 읽기 횟수는 4~5회)
조치 사항 및 개선점
긴급 알람을 표시하는 컬럼 추가
Technical document
9 / 18
alter table igt_mail_inbox add ugent char(1) default 'N'
메일 발송 시 ‘긴급’인 경우는, igt_mail_inbox 테이블의 ugent 컬럼에 ‘Y’ 입력 (mail_DB.html 수정)
포털 화면에서 긴급 메일 여부 확인
SELECT ugent
FROM igt_mail_inbox a, igt_mail b
WHERE a.doc_yearmon = b.doc_yearmon AND a.doc_number =b.doc_number
AND a.receiver= [client_id] AND a.recv_date IS NULL AND a.send_reserve
<= [current_date]
2.3 게시판 성능 개선
2.3.1 게시판 목록 (bbsList.html)
현행 쿼리
select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content
from igt_bbs_catalog
where bbs_id in ( '4200000', '4200000', '4200000e' ) order by bbs_id
문제점
order by 절로 인해서 임시 테이블(worktable)이 생성된다.
조치 사항 및 개선점
select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content
from igt_bbs_catalog
where bbs_id in ( '4200000', '4200000', '4200000e' )
order by 절을 생략해도, pk_igt_bbs_catalog 인덱스가 bbs_id 컬럼으로 정렬되어 있으므로 정확한 순서
대로 출력됨.
2.3.2 일반 및 동호회 게시판 목록 (bbsList.html, dept_tree.js)
현행 쿼리
select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content
Technical document
10 / 18
from igt_bbs_catalog
where bbs_type in ('bbs','sign','spec') and bbs_content in ('Y','N')
order by bbs_id
select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content
from igt_bbs_catalog
where bbs_type='cug' and bbs_id in (select cug_id from igt_user_role
where code_id >= '910' and userlog_id='17140') order by bbs_id
문제점
idx_bbs_catalog(bbs_type) 인덱스를 사용하나, 인덱스 사용으로 인해, worktable 발생.
조치 사항 및 개선점
인덱스를 사용하지 않도록 힌트(hint)를 제공하여, table scan을 유도 (테이블 크기가 작고 변경이 없으
므로, table scan이 유리)
select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content
from igt_bbs_catalog (index pk_igt_bbs_catalog)
where bbs_type in ('bbs','sign','spec') and bbs_content in ('Y','N')
order by bbs_id
select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content
from igt_bbs_catalog (index pk_igt_bbs_catalog)
where bbs_type='cug' and bbs_id in (select cug_id from igt_user_role
where code_id >= '910' and userlog_id='17140') order by bbs_id
3. 포털 성능 개선 3차
3.1 작업 개요
포털 로그인 시점에서 예약 메일 수신 확인 기능 적용 후 포털 화면에서 예약 메일 수신 처리(트랜
잭션 발생)로 인해서 포털 서비스 성능 저하.
예약 메일 수신 처리를 백그라운드 데몬 서비스로 분리 개발 및 적용.
3.2 예약 메일 수신 데몬
3.2.1 예약 메일 수신 쿼리
SELECT receiver, doc_yearmon, doc_number from igt_mail_inbox WHERE
recv_date is null and send_reserve <= getdate()
Technical document
11 / 18
3.2.2 예약 메일 인덱스 생성
CREATE INDEX idx_mail_inbox2 ON igt_mail_inbox(recv_date, send_reserve)
3.2.3 예약 메일 수신 프로그램
프로그램 위치 : /Groupware/softwares/test90/RecvResv
컴파일 스크립트 : compile.sh
실행 스크립트 : exec.sh
DB 환경 설정 : /Groupware/softwares/test90/RecvResv/jsp/sql/database.properties
3.2.4 작업 개요
- 서버 데몬 실행 스크립트를 실행하면, 30분에 한번씩 RecvResv 자바 어플리케이션 호출
- 예약된 메일 목록을 읽어낸 후, 수신자 메일함에 등록한다.
- 오류 메시지는 화면으로 출력함. (따라서, 로그 저장을 위해서는 redirection 사용해야 함)
4. 성능 개선 4차
4.1 작업 개요
메일 서비스의 느린 응답 시간 개선 및 서버 오류 분석/조치
4.2 메일 응답 성능 개선
index statistics 재성성
전자우편 서비스 쿼리 실행 시 인덱스를 정상적으로 활용하지 못하고 있음. index statistics 재생성하
여 인덱스 사용 효율을 높임. (논리적 읽기 성능 3배 증가)
update all statistics igt_mail_docfolder
메일 서비스의 DB 연결 수 증가
최대 데이터베이스 연결 수를 10에서 40으로 증가. 메일 웹 서버 프로세스가 2개이므로 총 80으로
증가.
메일 문서함 목록 페이지의 쿼리 튜닝
메일 문서함의 문서 건 수를 읽어내는 쿼리는 아래와 같음.
Technical document
12 / 18
select count(*) as cnt from igt_mail_docfolder where userlog_id='17140'
and convert(varchar(10),getdate(),111) =
convert(varchar(10),recv_date,111) and is_display='Y' and folder_id in
(1,10) AT isolation 0
isolation level 0 설정된 쿼리에 대한 query plan을 조회한 결과 PK 인덱스를 사용하고 있으며, 응답 성
능이 현저히 낮음.
The type of query is SELECT.
Evaluate Ungrouped COUNT AGGREGATE.
FROM TABLE
igt_mail_docfolder
Nested iteration.
Using Clustered Index.
Index : pk_igt_mail_docfolder
Forward scan.
Positioning at start of table.
Using I/O Size 4 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
SQL Server cpu time: 600 ms. SQL Server elapsed time: 1833 ms.
isolation 레벨 설정을 제거한 경우 아래와 같이 적절한 인덱스를 사용하며, 응답 시간이 1833ms에서
33ms로 향상되었음.
The type of query is SELECT.
Evaluate Ungrouped COUNT AGGREGATE.
FROM TABLE
igt_mail_docfolder
Nested iteration.
Using 2 Matching Index Scans
Index : idx_mail_docfolder2
Forward scan.
Positioning by key.
Keys are:
userlog_id ASC
folder_id ASC
is_display ASC
Index : idx_mail_docfolder2
Forward scan.
Positioning by key.
Keys are:
userlog_id ASC
Technical document
13 / 18
folder_id ASC
is_display ASC
Using I/O Size 4 Kbytes for data pages.
With LRU Buffer Replacement Strategy for data pages.
SQL Server cpu time: 0 ms. SQL Server elapsed time: 33 ms.
4.3 포털 서비스 장애 및 원인 분석
4.3.1 포털 서비스 장애
X월 XX일 오전 중 포털 서비스 일시 중단.
결재 서비스 개선을 위해 결재 웹 서버 프로세스를 중단하였고, 이를 포착한 HA 서비스에서 포털
서비스를 강제 재기동 하였음.
HA 서비스 해제하여 추후 재발하지 않도록 조치
4.3.2 포털 웹 서버 에러 로그 분석
포털 웹 서버 오류 로그 파일에 몇 가지 오류 메시지가 빈번하게 발생함.
no.html 파일을 못 찾는 오류
[08/Jan/2005:22:22:43] warning (5071): for host 10.10.16.31 trying to GET /, send-error reports: error opening
no.html (File not found)
사용자가 루트 페이지 경로를 웹 브라우저에 입력한 경우, 이는 서비스 페이지가 아니므로 위와 같
은 오류가 서버에 남고 사용자 화면에서는 ‘404 not found’ 메시지 표시.
/Groupware/AttVolume/Group 디렉토리에 빈 index.html 파일을 생성하여 위와 같은 오류 제거
cursor 관련 오류
[08/Jan/2005:22:22:43] warning ( 5071): for host 10.10.16.31 trying to GET /, send-error reports: error opening
no.html (File not found)
웹 서버 프로세스가 재기동한 후 웹 서버와 데이터베이스와의 연결이 초기화 되지 못하면 위와 같
은 오류가 빈번히 발생함. 웹 서버 기동 직후 즉시, 데이터베이스 연결이 복구되도록 groupware.js 파
일 수정
// DataBase Conneted..
function dbConnect( force )
{
// force 인자가 ‘true’로 전달되면, db 연결 상태 확인
// 아니면, db_connected 프로젝트 변수 상태를 확인하여,
Technical document
14 / 18
// DB 연결 상태이면 return
if( force == null && null2emp(project.db_connected) == 'true' )
return;
// DB와 연결되어 있지 않다면 연결
if( !database.connected() )
{
database.connect("SYBASE","GSVR","gw2user","gw2user","");
}
if( !database.connected() )
{
write("<script>");
write("alert('DATABASE가 DOWN되었습니다.관리자에게 연락하여 주십시
요!');");
write("</script>");
}
// DB 연결에 성공한 경우, db_connected 변수를 true로 설정
else
{
project.db_connected = 'true';
}
}
5. 성능 개선 5차
5.1 작업 개요
포털, 메일 및 게시 서비스 성능 개선.
5.2 포털 쿼리 튜닝
5.2.1 업무 공지 (gwTable1.html)
업무 공지 게시물 목록을 출력하면서, 각각의 게시물이 속한 게시판 이름을 쿼리하고 하는데, 업무
공지에서는 게시판 명칭을 출력하지 않기 때문에 쿼리를 삭제하였음.
5.2.2 최근 메일 (gwTable3.html)
포털 화면에 최근 메일 목록 화면 쿼리 시 화면에는 5건의 메일만을 출력하지만 쿼리 시에 읽어들
이는 레코드 수에 제한이 없으므로 쿼리 실행 시 set rowcount 5 제한을 부여하였음.
Technical document
15 / 18
5.3 메일 쿼리 튜닝
5.3.1 보낸 편지함에서 수신여부 쿼리
수신일자 및 회수 가능여부를 확인하는 쿼리가 가장 먼저 수신한 사용자만을 읽어들이기 때문에, 나
머지 레코드를 읽어낼(fetch) 필요가 없다. 따라서, set rowcount 1 제한을 부여하여 읽기 성능 개선.
5.3.2 메일 조회 시 이전 / 이후 문서 연결(link)
메일함의 문서를 조회할 때, 이전 및 이후 문서에 대한 연결을 표시하는 쿼리에 set rowcount 1 제한
을 부여하여 읽기 성능 개선.
5.3.3 메일 수신함의 보낸 사람(부서) 정보 조회
메일 수신함에서 각각의 메일을 보낸 사용자의 성명과 부서를 출력하기 위해서 수신 문서 수만큼의
쿼리가 발생한다.
현행 쿼리
SELECT org_id,userlog_name,userlog_real_name FROM igt_group
WHERE userlog_id = (select userlog_id from igt_member where
group_member='17140')
문제점
inner query를 사용하기 때문에 사실상 2번의 쿼리를 수행한다. 사이베이스에서는 inner query 보다는
join의 성능이 좋다고 판단된다.
조치사항 및 개선점
join 쿼리로 개선한 결과 실행 계획 상으로 2단계 쿼리가 한 단계로 줄어드는 효과 발생
SELECT g.org_id, g.userlog_name, g.userlog_real_name
FROM igt_group g, igt_member m
WHERE g.userlog_id = m.userlog_id AND m.group_member='17140'
5.4 게시 인덱스 튜닝
5.4.1 미열람 게시판 쿼리
가장 나은 성능 개선 효과를 가져왔음.
Technical document
16 / 18
현행 쿼리
SELECT count(1) as bNumber FROM igt_bbs WHERE doc_regdate > '2005-01-13'
and is_restrict not like 'Y' and resv_date <= getdate() and
doc_bbsid in
('001','002','102','201','202','203','204','205','206','207',
'208','209','301','302','303','304','401','402','403','404','501','502',
'503','504','601','602','603','604','620','621','701','702',
'703','704','705','99999','4200000', '4200000e' )
문제점
idx_bbs3(doc_bbsid, resv_date, doc_regdate) 인덱스를 사용하며, doc_bbsid 수만큼 인덱스를 반복하여 읽
어들인다. 현재 운영 중인 최근 게시판 수가 38개에 달하기 때문에 상당한 부하를 유발한다.
또한 이러한 쿼리가 미열람 게시판에서 5회에 걸쳐 수행된다.
(오늘 등록 게시물 열람 건수, 오늘 미열람 게시 건수, 최근 게시물 전체 건수, 사용자가 조회한 최
근 게시물 건 수, 게시물 목록 쿼리 등)
조치사항 및 개선점
idx_bbs2(doc_regdate, doc_urgency)를 사용하도록 힌트를 제공하여, 인덱스 스캔 횟수를 한번으로 감소
시킨다. 또한 최근 3일간의 게시물을 조회하기 때문에 인덱스 내부에서도 30~50개의 레코드만을 스
캔하게 됨으로써 효율이 극대화 된다.
산술적으로 38 * 5 (190)회에 걸친 인덱스 조회가 5회로 줄어든다. 또한 인덱스 조회 범위가 전체에서
1%이내로 감소함으로 잠정 효과는 약 50배 이상에 달한다.
SELECT count(1) as bNumber FROM igt_bbs (index idx_bbs2) WHERE
doc_regdate > '2005-01-13'
and is_restrict not like 'Y' and resv_date <= getdate() and
doc_bbsid in
('001','002','102','201','202','203','204','205','206','207',
'208','209','301','302','303','304','401','402','403','404','501','502',
'503','504','601','602','603','604','620','621','701','702',
'703','704','705','99999','4200000', '4200000e' )
6. 성능 개선 6차
6.1 작업 개요
포털, 메일 및 게시 서비스 성능 개선.
Technical document
17 / 18
6.2 메일 및 게시 페이지 당 출력 레코드 제한
메일, 게시판 목록의 페이지 당 출력 레코드 수를 50에서 20으로 감소
6.3 포털 쿼리 튜닝
6.3.1 최근 게시 (gwTable4.html)
최근게시 목록 추출 후 개별 게시물을 조회 했는지 여부를 확인하는 쿼리와 게시판 명칭을 추출하
는 쿼리를 실행하던 방식을 개선하여, 3종의 쿼리를 단일 쿼리로 통합하고, set rowcount 5 지정
set rowcount 5
select doc_writername, doc_bbsid, doc_yearmon, doc_number,
doc_subject, doc_writer, doc_regdate, writer_deptname, bbs_name
from igt_bbs (index idx_bbs2), igt_bbs_catalog
where doc_regdate > dateadd(dd,-3,getdate()) and doc_bbsid in
(select bbs_id from igt_bbs_env where userlog_id='17140')
and resv_date <= getdate() and is_restrict not like 'Y'
and doc_number not in (select doc_number from igt_bbs_read where
userlog_id='17140') and bbs_id = doc_bbsid
order by doc_regdate desc
6.3.2 업무공지 (gwTable1.html)
최근 업무공지 목록 추출 후 개별 게시물을 조회 했는지 여부를 확인하는 쿼리를 실행하던 방식을
개선하여, 2종의 쿼리를 단일 쿼리로 통합하고, set rowcount 5 지정
set rowcount 5
select doc_subject, doc_writername, doc_yearmon, doc_number,
writer_deptname, doc_regdate, doc_writer
from igt_bbs (index idx_bbs2)
where doc_regdate > dateadd(dd,-3,getdate()) and doc_bbsid = '102'
and resv_date <= getdate() and is_restrict not like 'Y'
and doc_number not in (select doc_number from igt_bbs_read where
userlog_id='17140')
order by doc_regdate desc
6.3.3 본부 공지 (gwTable2.html) 및 게시속보(gwMain_down.html)
위와 동일한 방식으로 튜닝
SELECT doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number,
doc_writer, doc_regdate, writer_deptname from igt_bbs (index idx_bbs2)
Technical document
18 / 18
where doc_bbsid in ( '4200000', '4200000', '4200000e') and
doc_regdate > dateadd(dd,-3,getdate()) and resv_date <= getdate()
and is_restrict not like 'Y' and doc_number not in (select doc_number
from igt_bbs_read where userlog_id='17140')
order by doc_regdate desc
select doc_bbsid, doc_subject, doc_yearmon, doc_number, doc_writer from
igt_bbs (index idx_bbs2) where doc_urgency='Y' and doc_regdate >
dateadd(dd,-1,getdate()) and resv_date <= getdate() and is_restrict not
like 'Y' and doc_number not in (select doc_number from igt_bbs_read
where userlog_id='17140') order by doc_regdate desc

More Related Content

Viewers also liked

소프트웨어의 동작 방식 이해
소프트웨어의 동작 방식 이해소프트웨어의 동작 방식 이해
소프트웨어의 동작 방식 이해중선 곽
 
Db 진단 및 튜닝 보고 (example)
Db 진단 및 튜닝 보고 (example)Db 진단 및 튜닝 보고 (example)
Db 진단 및 튜닝 보고 (example)중선 곽
 
객체지향 철학 그리고 5대 개념
객체지향 철학 그리고 5대 개념객체지향 철학 그리고 5대 개념
객체지향 철학 그리고 5대 개념중선 곽
 
프로그래머가 알아야 하는 2진수 기반의 컴퓨터 동작 원리
프로그래머가 알아야 하는 2진수 기반의 컴퓨터 동작 원리프로그래머가 알아야 하는 2진수 기반의 컴퓨터 동작 원리
프로그래머가 알아야 하는 2진수 기반의 컴퓨터 동작 원리중선 곽
 
메이븐 기본 이해
메이븐 기본 이해메이븐 기본 이해
메이븐 기본 이해중선 곽
 
컴퓨터 네트워크와 인터넷
컴퓨터 네트워크와 인터넷컴퓨터 네트워크와 인터넷
컴퓨터 네트워크와 인터넷중선 곽
 
프로그래머가 알아야 하는 메모리 관리 기법
프로그래머가 알아야 하는 메모리 관리 기법프로그래머가 알아야 하는 메모리 관리 기법
프로그래머가 알아야 하는 메모리 관리 기법중선 곽
 
서버 아키텍쳐 입문
서버 아키텍쳐 입문서버 아키텍쳐 입문
서버 아키텍쳐 입문중선 곽
 
서버 성능에 대한 정의와 이해
서버 성능에 대한 정의와 이해서버 성능에 대한 정의와 이해
서버 성능에 대한 정의와 이해중선 곽
 
Test driven development short lesson
Test driven development   short lessonTest driven development   short lesson
Test driven development short lesson중선 곽
 
포스트모템디버깅과 프로세스 덤프 실전
포스트모템디버깅과 프로세스 덤프 실전포스트모템디버깅과 프로세스 덤프 실전
포스트모템디버깅과 프로세스 덤프 실전주항 박
 
[실전 윈도우 디버깅] 13 포스트모템 디버깅
[실전 윈도우 디버깅] 13 포스트모템 디버깅[실전 윈도우 디버깅] 13 포스트모템 디버깅
[실전 윈도우 디버깅] 13 포스트모템 디버깅종빈 오
 
우분투 한국 커뮤니티 나눔모임 발표 2013-02-23
우분투 한국 커뮤니티 나눔모임 발표 2013-02-23우분투 한국 커뮤니티 나눔모임 발표 2013-02-23
우분투 한국 커뮤니티 나눔모임 발표 2013-02-23유명환 FunFun Yoo
 
Tomcat monitoring using_javamelody
Tomcat monitoring using_javamelodyTomcat monitoring using_javamelody
Tomcat monitoring using_javamelody중선 곽
 
운영체제 인트로
운영체제 인트로운영체제 인트로
운영체제 인트로Junnie Jobs
 
[제5회 KCD] 한국에서 커뮤니티를 운영한다는 건...
[제5회 KCD] 한국에서 커뮤니티를 운영한다는 건...[제5회 KCD] 한국에서 커뮤니티를 운영한다는 건...
[제5회 KCD] 한국에서 커뮤니티를 운영한다는 건...유명환 FunFun Yoo
 
창조경제 IoT 해커톤 교육 2일차 교육 자료
창조경제 IoT 해커톤 교육 2일차 교육 자료창조경제 IoT 해커톤 교육 2일차 교육 자료
창조경제 IoT 해커톤 교육 2일차 교육 자료유명환 FunFun Yoo
 
문돌이가 가르치는 웹 프론트엔드 기초 2차시
문돌이가 가르치는 웹 프론트엔드 기초 2차시문돌이가 가르치는 웹 프론트엔드 기초 2차시
문돌이가 가르치는 웹 프론트엔드 기초 2차시동현 조
 
[Codebakery 일반동아리] IoT의 개념 및 분야, 전망
[Codebakery 일반동아리] IoT의 개념 및 분야, 전망[Codebakery 일반동아리] IoT의 개념 및 분야, 전망
[Codebakery 일반동아리] IoT의 개념 및 분야, 전망동현 조
 

Viewers also liked (20)

소프트웨어의 동작 방식 이해
소프트웨어의 동작 방식 이해소프트웨어의 동작 방식 이해
소프트웨어의 동작 방식 이해
 
Db 진단 및 튜닝 보고 (example)
Db 진단 및 튜닝 보고 (example)Db 진단 및 튜닝 보고 (example)
Db 진단 및 튜닝 보고 (example)
 
객체지향 철학 그리고 5대 개념
객체지향 철학 그리고 5대 개념객체지향 철학 그리고 5대 개념
객체지향 철학 그리고 5대 개념
 
프로그래머가 알아야 하는 2진수 기반의 컴퓨터 동작 원리
프로그래머가 알아야 하는 2진수 기반의 컴퓨터 동작 원리프로그래머가 알아야 하는 2진수 기반의 컴퓨터 동작 원리
프로그래머가 알아야 하는 2진수 기반의 컴퓨터 동작 원리
 
메이븐 기본 이해
메이븐 기본 이해메이븐 기본 이해
메이븐 기본 이해
 
컴퓨터 네트워크와 인터넷
컴퓨터 네트워크와 인터넷컴퓨터 네트워크와 인터넷
컴퓨터 네트워크와 인터넷
 
프로그래머가 알아야 하는 메모리 관리 기법
프로그래머가 알아야 하는 메모리 관리 기법프로그래머가 알아야 하는 메모리 관리 기법
프로그래머가 알아야 하는 메모리 관리 기법
 
서버 아키텍쳐 입문
서버 아키텍쳐 입문서버 아키텍쳐 입문
서버 아키텍쳐 입문
 
서버 성능에 대한 정의와 이해
서버 성능에 대한 정의와 이해서버 성능에 대한 정의와 이해
서버 성능에 대한 정의와 이해
 
Test driven development short lesson
Test driven development   short lessonTest driven development   short lesson
Test driven development short lesson
 
포스트모템디버깅과 프로세스 덤프 실전
포스트모템디버깅과 프로세스 덤프 실전포스트모템디버깅과 프로세스 덤프 실전
포스트모템디버깅과 프로세스 덤프 실전
 
[실전 윈도우 디버깅] 13 포스트모템 디버깅
[실전 윈도우 디버깅] 13 포스트모템 디버깅[실전 윈도우 디버깅] 13 포스트모템 디버깅
[실전 윈도우 디버깅] 13 포스트모템 디버깅
 
우분투 한국 커뮤니티 나눔모임 발표 2013-02-23
우분투 한국 커뮤니티 나눔모임 발표 2013-02-23우분투 한국 커뮤니티 나눔모임 발표 2013-02-23
우분투 한국 커뮤니티 나눔모임 발표 2013-02-23
 
Tomcat monitoring using_javamelody
Tomcat monitoring using_javamelodyTomcat monitoring using_javamelody
Tomcat monitoring using_javamelody
 
운영체제 인트로
운영체제 인트로운영체제 인트로
운영체제 인트로
 
[제5회 KCD] 한국에서 커뮤니티를 운영한다는 건...
[제5회 KCD] 한국에서 커뮤니티를 운영한다는 건...[제5회 KCD] 한국에서 커뮤니티를 운영한다는 건...
[제5회 KCD] 한국에서 커뮤니티를 운영한다는 건...
 
창조경제 IoT 해커톤 교육 2일차 교육 자료
창조경제 IoT 해커톤 교육 2일차 교육 자료창조경제 IoT 해커톤 교육 2일차 교육 자료
창조경제 IoT 해커톤 교육 2일차 교육 자료
 
Hello std.io 유명환_20140125
Hello std.io 유명환_20140125Hello std.io 유명환_20140125
Hello std.io 유명환_20140125
 
문돌이가 가르치는 웹 프론트엔드 기초 2차시
문돌이가 가르치는 웹 프론트엔드 기초 2차시문돌이가 가르치는 웹 프론트엔드 기초 2차시
문돌이가 가르치는 웹 프론트엔드 기초 2차시
 
[Codebakery 일반동아리] IoT의 개념 및 분야, 전망
[Codebakery 일반동아리] IoT의 개념 및 분야, 전망[Codebakery 일반동아리] IoT의 개념 및 분야, 전망
[Codebakery 일반동아리] IoT의 개념 및 분야, 전망
 

Similar to Intranet query tuning (example)

대량의 DML 작업에 대한 성능개선방안_Wh oracle
대량의 DML 작업에 대한 성능개선방안_Wh oracle대량의 DML 작업에 대한 성능개선방안_Wh oracle
대량의 DML 작업에 대한 성능개선방안_Wh oracle엑셈
 
[SPONGE] E.BLOCK+ [10] final portfolio(181012)
[SPONGE] E.BLOCK+ [10] final portfolio(181012)[SPONGE] E.BLOCK+ [10] final portfolio(181012)
[SPONGE] E.BLOCK+ [10] final portfolio(181012)LeeJeongRyeol
 
Ndc2011 성능 향상을_위한_데이터베이스_아키텍쳐_구축_및_개발_가이드
Ndc2011 성능 향상을_위한_데이터베이스_아키텍쳐_구축_및_개발_가이드Ndc2011 성능 향상을_위한_데이터베이스_아키텍쳐_구축_및_개발_가이드
Ndc2011 성능 향상을_위한_데이터베이스_아키텍쳐_구축_및_개발_가이드cranbe95
 
[오픈소스컨설팅]Performance Tuning How To
[오픈소스컨설팅]Performance Tuning How To[오픈소스컨설팅]Performance Tuning How To
[오픈소스컨설팅]Performance Tuning How ToJi-Woong Choi
 
19.컴퓨터 네트워크 program homework
19.컴퓨터 네트워크 program homework19.컴퓨터 네트워크 program homework
19.컴퓨터 네트워크 program homework호상 장
 
MariaDB 마이그레이션 - 네오클로바
MariaDB 마이그레이션 - 네오클로바MariaDB 마이그레이션 - 네오클로바
MariaDB 마이그레이션 - 네오클로바NeoClova
 
Web Analytics at Scale with Elasticsearch @ naver.com - Part 2 - Lessons Learned
Web Analytics at Scale with Elasticsearch @ naver.com - Part 2 - Lessons LearnedWeb Analytics at Scale with Elasticsearch @ naver.com - Part 2 - Lessons Learned
Web Analytics at Scale with Elasticsearch @ naver.com - Part 2 - Lessons LearnedJungsu Heo
 
DB Monitoring 개념 및 활용 (박명규)
DB Monitoring 개념 및 활용 (박명규)DB Monitoring 개념 및 활용 (박명규)
DB Monitoring 개념 및 활용 (박명규)WhaTap Labs
 
Windows 성능모니터를 이용한 SQL Server 성능 분석
Windows 성능모니터를 이용한 SQL Server 성능 분석Windows 성능모니터를 이용한 SQL Server 성능 분석
Windows 성능모니터를 이용한 SQL Server 성능 분석Sung wook Kang
 
Spring batch와 함께 하는 TDD
Spring batch와 함께 하는 TDDSpring batch와 함께 하는 TDD
Spring batch와 함께 하는 TDDSanghyuk Jung
 
Big query at GDG Korea Cloud meetup
Big query at GDG Korea Cloud meetupBig query at GDG Korea Cloud meetup
Big query at GDG Korea Cloud meetupJude Kim
 
제1회 Tech Net Sql Server 2005 T Sql Enhancements
제1회 Tech Net Sql Server 2005 T Sql Enhancements제1회 Tech Net Sql Server 2005 T Sql Enhancements
제1회 Tech Net Sql Server 2005 T Sql Enhancementsbeamofhope
 
실전 DataSnap!
실전 DataSnap!실전 DataSnap!
실전 DataSnap!Devgear
 
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]MongoDB
 
자동화빌드서버
자동화빌드서버자동화빌드서버
자동화빌드서버성기 홍
 
R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1happychallenge
 
HTTP/3 시대의 웹 성능 최적화 기술 이해하기
HTTP/3 시대의 웹 성능 최적화 기술 이해하기HTTP/3 시대의 웹 성능 최적화 기술 이해하기
HTTP/3 시대의 웹 성능 최적화 기술 이해하기SangJin Kang
 
visualPrinting 개선안(22.4.04).pptx
visualPrinting 개선안(22.4.04).pptxvisualPrinting 개선안(22.4.04).pptx
visualPrinting 개선안(22.4.04).pptxssuser89c688
 

Similar to Intranet query tuning (example) (20)

대량의 DML 작업에 대한 성능개선방안_Wh oracle
대량의 DML 작업에 대한 성능개선방안_Wh oracle대량의 DML 작업에 대한 성능개선방안_Wh oracle
대량의 DML 작업에 대한 성능개선방안_Wh oracle
 
[SPONGE] E.BLOCK+ [10] final portfolio(181012)
[SPONGE] E.BLOCK+ [10] final portfolio(181012)[SPONGE] E.BLOCK+ [10] final portfolio(181012)
[SPONGE] E.BLOCK+ [10] final portfolio(181012)
 
Ndc2011 성능 향상을_위한_데이터베이스_아키텍쳐_구축_및_개발_가이드
Ndc2011 성능 향상을_위한_데이터베이스_아키텍쳐_구축_및_개발_가이드Ndc2011 성능 향상을_위한_데이터베이스_아키텍쳐_구축_및_개발_가이드
Ndc2011 성능 향상을_위한_데이터베이스_아키텍쳐_구축_및_개발_가이드
 
[오픈소스컨설팅]Performance Tuning How To
[오픈소스컨설팅]Performance Tuning How To[오픈소스컨설팅]Performance Tuning How To
[오픈소스컨설팅]Performance Tuning How To
 
19.컴퓨터 네트워크 program homework
19.컴퓨터 네트워크 program homework19.컴퓨터 네트워크 program homework
19.컴퓨터 네트워크 program homework
 
MariaDB 마이그레이션 - 네오클로바
MariaDB 마이그레이션 - 네오클로바MariaDB 마이그레이션 - 네오클로바
MariaDB 마이그레이션 - 네오클로바
 
Redis
RedisRedis
Redis
 
Web Analytics at Scale with Elasticsearch @ naver.com - Part 2 - Lessons Learned
Web Analytics at Scale with Elasticsearch @ naver.com - Part 2 - Lessons LearnedWeb Analytics at Scale with Elasticsearch @ naver.com - Part 2 - Lessons Learned
Web Analytics at Scale with Elasticsearch @ naver.com - Part 2 - Lessons Learned
 
DB Monitoring 개념 및 활용 (박명규)
DB Monitoring 개념 및 활용 (박명규)DB Monitoring 개념 및 활용 (박명규)
DB Monitoring 개념 및 활용 (박명규)
 
Windows 성능모니터를 이용한 SQL Server 성능 분석
Windows 성능모니터를 이용한 SQL Server 성능 분석Windows 성능모니터를 이용한 SQL Server 성능 분석
Windows 성능모니터를 이용한 SQL Server 성능 분석
 
Spring batch와 함께 하는 TDD
Spring batch와 함께 하는 TDDSpring batch와 함께 하는 TDD
Spring batch와 함께 하는 TDD
 
Big query at GDG Korea Cloud meetup
Big query at GDG Korea Cloud meetupBig query at GDG Korea Cloud meetup
Big query at GDG Korea Cloud meetup
 
제1회 Tech Net Sql Server 2005 T Sql Enhancements
제1회 Tech Net Sql Server 2005 T Sql Enhancements제1회 Tech Net Sql Server 2005 T Sql Enhancements
제1회 Tech Net Sql Server 2005 T Sql Enhancements
 
NO PARALLEL DML
NO PARALLEL DMLNO PARALLEL DML
NO PARALLEL DML
 
실전 DataSnap!
실전 DataSnap!실전 DataSnap!
실전 DataSnap!
 
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
 
자동화빌드서버
자동화빌드서버자동화빌드서버
자동화빌드서버
 
R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1
 
HTTP/3 시대의 웹 성능 최적화 기술 이해하기
HTTP/3 시대의 웹 성능 최적화 기술 이해하기HTTP/3 시대의 웹 성능 최적화 기술 이해하기
HTTP/3 시대의 웹 성능 최적화 기술 이해하기
 
visualPrinting 개선안(22.4.04).pptx
visualPrinting 개선안(22.4.04).pptxvisualPrinting 개선안(22.4.04).pptx
visualPrinting 개선안(22.4.04).pptx
 

More from 중선 곽

Web service performance_test_using_jmeter_ver1.2
Web service performance_test_using_jmeter_ver1.2Web service performance_test_using_jmeter_ver1.2
Web service performance_test_using_jmeter_ver1.2중선 곽
 
Java rmi 개발 가이드
Java rmi 개발 가이드Java rmi 개발 가이드
Java rmi 개발 가이드중선 곽
 
Java rmi 개발 가이드
Java rmi 개발 가이드Java rmi 개발 가이드
Java rmi 개발 가이드중선 곽
 
자바 직렬화 (Java serialization)
자바 직렬화 (Java serialization)자바 직렬화 (Java serialization)
자바 직렬화 (Java serialization)중선 곽
 
숫자 구분자 처리 (Digit group separators)
숫자 구분자 처리 (Digit group separators)숫자 구분자 처리 (Digit group separators)
숫자 구분자 처리 (Digit group separators)중선 곽
 
서버 아키텍쳐 입문
서버 아키텍쳐 입문서버 아키텍쳐 입문
서버 아키텍쳐 입문중선 곽
 
Apache ZooKeeper 소개
Apache ZooKeeper 소개Apache ZooKeeper 소개
Apache ZooKeeper 소개중선 곽
 
Effective java 1 and 2
Effective java 1 and 2Effective java 1 and 2
Effective java 1 and 2중선 곽
 
지식경영 이해
지식경영 이해지식경영 이해
지식경영 이해중선 곽
 
Continue break goto_에_대한_고찰
Continue break goto_에_대한_고찰Continue break goto_에_대한_고찰
Continue break goto_에_대한_고찰중선 곽
 
폰노이만 머신 이해
폰노이만 머신 이해폰노이만 머신 이해
폰노이만 머신 이해중선 곽
 

More from 중선 곽 (11)

Web service performance_test_using_jmeter_ver1.2
Web service performance_test_using_jmeter_ver1.2Web service performance_test_using_jmeter_ver1.2
Web service performance_test_using_jmeter_ver1.2
 
Java rmi 개발 가이드
Java rmi 개발 가이드Java rmi 개발 가이드
Java rmi 개발 가이드
 
Java rmi 개발 가이드
Java rmi 개발 가이드Java rmi 개발 가이드
Java rmi 개발 가이드
 
자바 직렬화 (Java serialization)
자바 직렬화 (Java serialization)자바 직렬화 (Java serialization)
자바 직렬화 (Java serialization)
 
숫자 구분자 처리 (Digit group separators)
숫자 구분자 처리 (Digit group separators)숫자 구분자 처리 (Digit group separators)
숫자 구분자 처리 (Digit group separators)
 
서버 아키텍쳐 입문
서버 아키텍쳐 입문서버 아키텍쳐 입문
서버 아키텍쳐 입문
 
Apache ZooKeeper 소개
Apache ZooKeeper 소개Apache ZooKeeper 소개
Apache ZooKeeper 소개
 
Effective java 1 and 2
Effective java 1 and 2Effective java 1 and 2
Effective java 1 and 2
 
지식경영 이해
지식경영 이해지식경영 이해
지식경영 이해
 
Continue break goto_에_대한_고찰
Continue break goto_에_대한_고찰Continue break goto_에_대한_고찰
Continue break goto_에_대한_고찰
 
폰노이만 머신 이해
폰노이만 머신 이해폰노이만 머신 이해
폰노이만 머신 이해
 

Intranet query tuning (example)

  • 1. Database query tuning (포털 서비스 응답 성능 개선) 2016년 03월 04일 (곽중선)
  • 2. Technical document 2 / 18 1. 포털 성능 개선 1.1 작업 개요 모 언론사 사내 인트라넷 서비스의 응답 성능 개선 작업 포털 서비스의 응답 속도가 현저히 저하되어 사용자들의 업무에 지장을 초래하고 있으며, 이에 포털 서비스의 쿼리 성능을 분석하고 튜닝하였음. 1.2 개선 내용 1.2.1 최근 게시 목록 현행 쿼리 SELECT doc_bbsid, doc_subject, doc_yearmon, doc_number, doc_writer FROM igt_bbs WHERE doc_urgency='Y' and doc_regdate > dateadd(dd,-1,getdate()) AND resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) AND is_restrict not like 'Y' order by doc_seq desc, doc_subseq asc 문제점 order by 절로 인해서 임시 테이블(worktable)이 생성되며, 포털 서비스에 사용자 접속 수가 증가할 경 우 자원의 부족이 발생하고 응답속도가 떨어짐. 조치 사항 및 개선점 SELECT doc_bbsid, doc_subject, doc_yearmon, doc_number, doc_writer FROM igt_bbs WHERE doc_urgency='Y' and doc_regdate > dateadd(dd,-1,getdate()) AND resv_date <= getdate() AND is_restrict not like 'Y' order by doc_regdate desc order by 절을 개선하여 임시 테이블이 생성되지 않도록 하였고, 쿼리 실행 단계가 2단계에서 1단계 로 단축되었음. 또한, 불필요한 조건을 제거하여 쿼리를 단순화 시킴 1.2.2 공지 확인 현행 쿼리 SELECT ltrim(notice_info) a FROM igt_notice WHERE userlog_id='17140'
  • 3. Technical document 3 / 18 문제점 사용자가 공지 알림을 확인하였는지 확인하는 쿼리. ltrim 함수가 쿼리에 포함되어 있으므로 쿼리 실 행 시 인덱스를 사용하지 못하고, 3천여건에 달하는 레코드를 전부 조회함 조치 사항 및 개선점 SELECT notice_info a FROM igt_notice WHERE userlog_id='17140' if(ninfo == "") -> if(ninfo.indexOf("Y") == -1 ) 쿼리 상에서 함수를 사용하지 않도록 변경하고, 자바 스크립트 소스를 수정함. 인덱스를 사용함으로 쿼리 성능이 개선되었음. 1.2.3 긴급 메일 알람 현행 쿼리 SELECT count(*) as cnt FROM igt_mail_inbox a, igt_mail b WHERE a.doc_yearmon = b.doc_yearmon AND a.doc_number =b.doc_number AND a.receiver= [client_id] AND a.recv_date IS NULL AND a.send_reserve <= [current_date] AND b.doc_spec ='긴급' 문제점 사용자의 수신 메일 중 긴급 메일에 한정하여 수신 건수를 출력하도록 개선하였으나, 그룹웨어 테이 블 중에서 데이터 양이 매우 많은 전자우편 테이블 2가지를 조인(join)함으로써 성능 저하 발생. 임시 테이블(worktable)이 생성되지는 않지만, 데이터 건수가 많음으로 인해서 논리적 읽기 횟수가 90 정도로 상당히 높음. (포털의 여타 쿼리들의 평균 논리적 읽기 횟수는 4~5회) 조치 사항 및 개선점 메일 수신 건수를 출력하지 않도록 변경함. 1.3 차주 작업 계획 1.3.1 메일 긴급 개선 알림 임시로 제거한 메일 알람 기능을 복원. 메일 발송 시 긴급 메일인 경우, igt_mail_inbox(메일 수신 알람) 테이블에 기록함으로써 수신 측 포털 페이지에서 쿼리 시 조인(join)을 사용하지 않고 수신 확인토록 변경
  • 4. Technical document 4 / 18 1.3.2 게시판 성능 개선 게시판 전반에 걸쳐 2차 프로젝트 이후 다음과 같은 변동으로 성능 저하 발생  쿼리 복잡도가 증가  페이지 당 출력 레코드 수 증가  게시판 수 증가 (10배 가량) 이에 게시판 전반에 걸쳐 쿼리 수행 시 임시 테이블(worktable)이 발생하고, 출력 성능이 낮아짐. 1.3.3 포털 성능 개선 업무 공지 / 최근 소식 / 부서 공지 SELECT doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number, doc_writer, doc_regdate , writer_deptname from igt_bbs where doc_bbsid in ( '4200000', '4200000', '4200000e') and doc_regdate > dateadd(dd,-3,getdate()) and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) and is_restrict not like 'Y' order by doc_regdate desc 게시판 쿼리가 복잡하여, 임시 테이블이 발생함. 인덱스 개선 혹은 쿼리 변경 등 검토 필요. 메일 수신 내역 select a.doc_yearmon,a.doc_number,b.doc_subject,b.doc_writer,b.doc_writername,b .doc_spec,b.doc_type,a.doc_open, a.folder_date as openedDate, a.recv_name from igt_mail_docfolder a, igt_mail b where a.doc_yearmon = b.doc_yearmon and a.doc_number = b.doc_number and a.userlog_id = '17140' and a.is_display = 'Y' and a.folder_id = 10 and a.doc_open = 'N' order by a.send_date desc 메일 수신 내역 쿼리가 복잡하여, 임시 테이블이 발생함. 인덱스 개선 등 검토 필요. 2. 포털 성능 개선 2차 2.1 작업 개요 사내 포털 서비스의 응답 성능 개선 작업 포털 서비스 1차 응답 성능 개선 이후, 포털 게시판 성능개선
  • 5. Technical document 5 / 18 2.2 포털 성능 개선 2.2.1 업무공지 (gwTable1.html) 현행 쿼리 select doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number, writer_deptname, convert(varchar(10),doc_regdate,111) || ' ' || convert(varchar(5),doc_regdate,108) as doc_regdate ,doc_writer from igt_bbs where doc_regdate > dateadd(dd,-3,getdate()) and (doc_bbsid='102') and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) and is_restrict not like 'Y' order by doc_regdate desc 문제점 convert 함수 사용으로 인해, worktable 발생. 조치 사항 및 개선점 select doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number, writer_deptname, doc_regdate ,doc_writer from igt_bbs (index idx_bbs2) where doc_regdate > dateadd(dd,-3,getdate()) and (doc_bbsid='102') and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) and is_restrict not like 'Y' order by doc_regdate desc doc_regdate를 convert함수로 변환하지 않고 바로 읽어내면, 자바스크립트의 Date type으로 변환 (conversion) 된다. Date 타입 객체를 문자열로 변환하기 위해 자바스크립트의 date2str() 함수를 /Lib/groupware.js 파일에 추하였고, 결론적으로 worktable이 생성되지 않음. 또한, index hint를 적용하였 음. 아래는 groupware.js 파일에 추가된 date2str 함수 소스이다. // Date 객체를 문자열로 변환 'YYYY/MM/DD HH24:MI' function date2str( _date ) { // 년도 추출 var strYear = _date.getYear(); // 월 추출 var nMonth = _date.getMonth() + 1; var strMonth = ''; if( nMonth < 10 ) strMonth = '0' + nMonth;
  • 6. Technical document 6 / 18 else strMonth = '' + nMonth; // 일자 추출 var nDate = _date.getDate(); var strDate = ''; if( nDate < 10 ) strDate = '0' + nDate; else strDate = '' + nDate; // 시 추출 var nHour = _date.getHours() + 1; var strHour = ''; if( nHour < 10 ) strHour = '0' + nHour; else strHour = '' + nHour; // 분 추출 var nMin = _date.getMinutes() + 1; var strMin = ''; if( nMin < 10 ) strMin = '0' + nMin; else strMin = '' + nMin; return strYear + '/' + strMonth + '/' + strDate + ' ' + strHour + ':' + strMin; } date2str 사용 예제는 아래와 같다. cursor = database.cursor( "select doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number,writer_deptname, doc_regdate, doc_writer from igt_bbs (index idx_bbs2) where doc_regdate > dateadd(dd,-3,"+now_date()+") and (doc_bbsid='102') and resv_date <= "+now_date()+" and resv_date > dateadd(dd,-30,"+now_date()+") and is_restrict not like 'Y' order by doc_regdate desc" ); // 화면에 최대 5개까지 항목을 보여준다. for( i=0; cursor.next() && i<5; i++ ) { record_set1[lc] = cursor.doc_bbsid; record_set2[lc] = cursor.doc_subject; record_set3[lc] = cursor.doc_writername; record_set4[lc] = cursor.doc_yearmon; record_set5[lc] = cursor.doc_number; record_set6[lc] = cur_dept.bbs_name;
  • 7. Technical document 7 / 18 record_set7[lc] = cursor.doc_writer; record_set8[lc] = date2str(cursor.doc_regdate); record_set9[lc] = cursor.writer_deptname; } cursor.close(); 2.2.2 본부 공지 (gwTable2.html) 현행 쿼리 SELECT doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number, doc_writer, convert(varchar(10),doc_regdate,111) || ' ' || convert(varchar(5),doc_regdate,108) as doc_regdate , writer_deptname from igt_bbs where doc_bbsid in ( '4200000', '4200000', '4200000e') and doc_regdate > dateadd(dd,-3,getdate()) and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) and is_restrict not like 'Y' order by doc_regdate desc 문제점 convert 함수 사용 및 doc_bbsid 컬럼에 대한 OR 조건(in 절)으로 인해 worktable 발생. 조치 사항 및 개선점 SELECT doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number, doc_writer, doc_regdate , writer_deptname from igt_bbs (index idx_bbs2) where doc_regdate > dateadd(dd,-3,getdate()) and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) and is_restrict not like 'Y' order by doc_regdate desc doc_regdate를 읽어내고, Date 타입 객체를 date2str 함수를 이용해 문자열로 변환함에 따라 worktable 이 생성되지 않음. 인덱스 힌트 사용 2.2.3 최근 게시 (gwTable4.html) 현행 쿼리 select doc_writername, doc_bbsid, doc_yearmon, doc_number, doc_subject,
  • 8. Technical document 8 / 18 doc_writer, convert(varchar(10),doc_regdate,111) || ' ' || convert(varchar(5),doc_regdate,108) as doc_regdate, writer_deptname from igt_bbs where doc_regdate > dateadd(dd,-3,getdate()) and doc_bbsid in (select bbs_id from igt_bbs_env where userlog_id='17140') and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) and is_restrict not like 'Y' order by doc_regdate desc 문제점 convert 함수 사용으로 인해 worktable 발생. 조치 사항 및 개선점 select doc_writername, doc_bbsid, doc_yearmon, doc_number, doc_subject, doc_writer, doc_regdate doc_regdate, writer_deptname from igt_bbs (index idx_bbs2) where doc_regdate > dateadd(dd,-3,getdate()) and doc_bbsid in (select bbs_id from igt_bbs_env where userlog_id='17140') and resv_date <= getdate() and resv_date > dateadd(dd,-30,getdate()) and is_restrict not like 'Y' order by doc_regdate desc doc_regdate를 읽어내고, Date 타입 객체를 date2str 함수를 이용해 문자열로 변환함에 따라 worktable 이 생성되지 않음. 인덱스 힌트 사용 2.2.4 긴급 메일 알람 현행 쿼리 SELECT count(*) as cnt FROM igt_mail_inbox a, igt_mail b WHERE a.doc_yearmon = b.doc_yearmon AND a.doc_number =b.doc_number AND a.receiver= [client_id] AND a.recv_date IS NULL AND a.send_reserve <= [current_date] AND b.doc_spec ='긴급' 문제점 사용자의 수신 메일 중 긴급 메일에 한정하여 수신 건수를 출력하도록 개선하였으나, 그룹웨어 테이 블 중에서 데이터 양이 매우 많은 전자우편 테이블 2가지를 조인(join)함으로써 성능 저하 발생. 임시 테이블(worktable)이 생성되지는 않지만, 데이터 건수가 많음으로 인해서 논리적 읽기 횟수가 90 정도로 상당히 높음. (포털의 여타 쿼리들의 평균 논리적 읽기 횟수는 4~5회) 조치 사항 및 개선점 긴급 알람을 표시하는 컬럼 추가
  • 9. Technical document 9 / 18 alter table igt_mail_inbox add ugent char(1) default 'N' 메일 발송 시 ‘긴급’인 경우는, igt_mail_inbox 테이블의 ugent 컬럼에 ‘Y’ 입력 (mail_DB.html 수정) 포털 화면에서 긴급 메일 여부 확인 SELECT ugent FROM igt_mail_inbox a, igt_mail b WHERE a.doc_yearmon = b.doc_yearmon AND a.doc_number =b.doc_number AND a.receiver= [client_id] AND a.recv_date IS NULL AND a.send_reserve <= [current_date] 2.3 게시판 성능 개선 2.3.1 게시판 목록 (bbsList.html) 현행 쿼리 select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content from igt_bbs_catalog where bbs_id in ( '4200000', '4200000', '4200000e' ) order by bbs_id 문제점 order by 절로 인해서 임시 테이블(worktable)이 생성된다. 조치 사항 및 개선점 select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content from igt_bbs_catalog where bbs_id in ( '4200000', '4200000', '4200000e' ) order by 절을 생략해도, pk_igt_bbs_catalog 인덱스가 bbs_id 컬럼으로 정렬되어 있으므로 정확한 순서 대로 출력됨. 2.3.2 일반 및 동호회 게시판 목록 (bbsList.html, dept_tree.js) 현행 쿼리 select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content
  • 10. Technical document 10 / 18 from igt_bbs_catalog where bbs_type in ('bbs','sign','spec') and bbs_content in ('Y','N') order by bbs_id select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content from igt_bbs_catalog where bbs_type='cug' and bbs_id in (select cug_id from igt_user_role where code_id >= '910' and userlog_id='17140') order by bbs_id 문제점 idx_bbs_catalog(bbs_type) 인덱스를 사용하나, 인덱스 사용으로 인해, worktable 발생. 조치 사항 및 개선점 인덱스를 사용하지 않도록 힌트(hint)를 제공하여, table scan을 유도 (테이블 크기가 작고 변경이 없으 므로, table scan이 유리) select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content from igt_bbs_catalog (index pk_igt_bbs_catalog) where bbs_type in ('bbs','sign','spec') and bbs_content in ('Y','N') order by bbs_id select bbs_id, bbs_type, bbs_name, bbs_indent, child_cnt, bbs_content from igt_bbs_catalog (index pk_igt_bbs_catalog) where bbs_type='cug' and bbs_id in (select cug_id from igt_user_role where code_id >= '910' and userlog_id='17140') order by bbs_id 3. 포털 성능 개선 3차 3.1 작업 개요 포털 로그인 시점에서 예약 메일 수신 확인 기능 적용 후 포털 화면에서 예약 메일 수신 처리(트랜 잭션 발생)로 인해서 포털 서비스 성능 저하. 예약 메일 수신 처리를 백그라운드 데몬 서비스로 분리 개발 및 적용. 3.2 예약 메일 수신 데몬 3.2.1 예약 메일 수신 쿼리 SELECT receiver, doc_yearmon, doc_number from igt_mail_inbox WHERE recv_date is null and send_reserve <= getdate()
  • 11. Technical document 11 / 18 3.2.2 예약 메일 인덱스 생성 CREATE INDEX idx_mail_inbox2 ON igt_mail_inbox(recv_date, send_reserve) 3.2.3 예약 메일 수신 프로그램 프로그램 위치 : /Groupware/softwares/test90/RecvResv 컴파일 스크립트 : compile.sh 실행 스크립트 : exec.sh DB 환경 설정 : /Groupware/softwares/test90/RecvResv/jsp/sql/database.properties 3.2.4 작업 개요 - 서버 데몬 실행 스크립트를 실행하면, 30분에 한번씩 RecvResv 자바 어플리케이션 호출 - 예약된 메일 목록을 읽어낸 후, 수신자 메일함에 등록한다. - 오류 메시지는 화면으로 출력함. (따라서, 로그 저장을 위해서는 redirection 사용해야 함) 4. 성능 개선 4차 4.1 작업 개요 메일 서비스의 느린 응답 시간 개선 및 서버 오류 분석/조치 4.2 메일 응답 성능 개선 index statistics 재성성 전자우편 서비스 쿼리 실행 시 인덱스를 정상적으로 활용하지 못하고 있음. index statistics 재생성하 여 인덱스 사용 효율을 높임. (논리적 읽기 성능 3배 증가) update all statistics igt_mail_docfolder 메일 서비스의 DB 연결 수 증가 최대 데이터베이스 연결 수를 10에서 40으로 증가. 메일 웹 서버 프로세스가 2개이므로 총 80으로 증가. 메일 문서함 목록 페이지의 쿼리 튜닝 메일 문서함의 문서 건 수를 읽어내는 쿼리는 아래와 같음.
  • 12. Technical document 12 / 18 select count(*) as cnt from igt_mail_docfolder where userlog_id='17140' and convert(varchar(10),getdate(),111) = convert(varchar(10),recv_date,111) and is_display='Y' and folder_id in (1,10) AT isolation 0 isolation level 0 설정된 쿼리에 대한 query plan을 조회한 결과 PK 인덱스를 사용하고 있으며, 응답 성 능이 현저히 낮음. The type of query is SELECT. Evaluate Ungrouped COUNT AGGREGATE. FROM TABLE igt_mail_docfolder Nested iteration. Using Clustered Index. Index : pk_igt_mail_docfolder Forward scan. Positioning at start of table. Using I/O Size 4 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. SQL Server cpu time: 600 ms. SQL Server elapsed time: 1833 ms. isolation 레벨 설정을 제거한 경우 아래와 같이 적절한 인덱스를 사용하며, 응답 시간이 1833ms에서 33ms로 향상되었음. The type of query is SELECT. Evaluate Ungrouped COUNT AGGREGATE. FROM TABLE igt_mail_docfolder Nested iteration. Using 2 Matching Index Scans Index : idx_mail_docfolder2 Forward scan. Positioning by key. Keys are: userlog_id ASC folder_id ASC is_display ASC Index : idx_mail_docfolder2 Forward scan. Positioning by key. Keys are: userlog_id ASC
  • 13. Technical document 13 / 18 folder_id ASC is_display ASC Using I/O Size 4 Kbytes for data pages. With LRU Buffer Replacement Strategy for data pages. SQL Server cpu time: 0 ms. SQL Server elapsed time: 33 ms. 4.3 포털 서비스 장애 및 원인 분석 4.3.1 포털 서비스 장애 X월 XX일 오전 중 포털 서비스 일시 중단. 결재 서비스 개선을 위해 결재 웹 서버 프로세스를 중단하였고, 이를 포착한 HA 서비스에서 포털 서비스를 강제 재기동 하였음. HA 서비스 해제하여 추후 재발하지 않도록 조치 4.3.2 포털 웹 서버 에러 로그 분석 포털 웹 서버 오류 로그 파일에 몇 가지 오류 메시지가 빈번하게 발생함. no.html 파일을 못 찾는 오류 [08/Jan/2005:22:22:43] warning (5071): for host 10.10.16.31 trying to GET /, send-error reports: error opening no.html (File not found) 사용자가 루트 페이지 경로를 웹 브라우저에 입력한 경우, 이는 서비스 페이지가 아니므로 위와 같 은 오류가 서버에 남고 사용자 화면에서는 ‘404 not found’ 메시지 표시. /Groupware/AttVolume/Group 디렉토리에 빈 index.html 파일을 생성하여 위와 같은 오류 제거 cursor 관련 오류 [08/Jan/2005:22:22:43] warning ( 5071): for host 10.10.16.31 trying to GET /, send-error reports: error opening no.html (File not found) 웹 서버 프로세스가 재기동한 후 웹 서버와 데이터베이스와의 연결이 초기화 되지 못하면 위와 같 은 오류가 빈번히 발생함. 웹 서버 기동 직후 즉시, 데이터베이스 연결이 복구되도록 groupware.js 파 일 수정 // DataBase Conneted.. function dbConnect( force ) { // force 인자가 ‘true’로 전달되면, db 연결 상태 확인 // 아니면, db_connected 프로젝트 변수 상태를 확인하여,
  • 14. Technical document 14 / 18 // DB 연결 상태이면 return if( force == null && null2emp(project.db_connected) == 'true' ) return; // DB와 연결되어 있지 않다면 연결 if( !database.connected() ) { database.connect("SYBASE","GSVR","gw2user","gw2user",""); } if( !database.connected() ) { write("<script>"); write("alert('DATABASE가 DOWN되었습니다.관리자에게 연락하여 주십시 요!');"); write("</script>"); } // DB 연결에 성공한 경우, db_connected 변수를 true로 설정 else { project.db_connected = 'true'; } } 5. 성능 개선 5차 5.1 작업 개요 포털, 메일 및 게시 서비스 성능 개선. 5.2 포털 쿼리 튜닝 5.2.1 업무 공지 (gwTable1.html) 업무 공지 게시물 목록을 출력하면서, 각각의 게시물이 속한 게시판 이름을 쿼리하고 하는데, 업무 공지에서는 게시판 명칭을 출력하지 않기 때문에 쿼리를 삭제하였음. 5.2.2 최근 메일 (gwTable3.html) 포털 화면에 최근 메일 목록 화면 쿼리 시 화면에는 5건의 메일만을 출력하지만 쿼리 시에 읽어들 이는 레코드 수에 제한이 없으므로 쿼리 실행 시 set rowcount 5 제한을 부여하였음.
  • 15. Technical document 15 / 18 5.3 메일 쿼리 튜닝 5.3.1 보낸 편지함에서 수신여부 쿼리 수신일자 및 회수 가능여부를 확인하는 쿼리가 가장 먼저 수신한 사용자만을 읽어들이기 때문에, 나 머지 레코드를 읽어낼(fetch) 필요가 없다. 따라서, set rowcount 1 제한을 부여하여 읽기 성능 개선. 5.3.2 메일 조회 시 이전 / 이후 문서 연결(link) 메일함의 문서를 조회할 때, 이전 및 이후 문서에 대한 연결을 표시하는 쿼리에 set rowcount 1 제한 을 부여하여 읽기 성능 개선. 5.3.3 메일 수신함의 보낸 사람(부서) 정보 조회 메일 수신함에서 각각의 메일을 보낸 사용자의 성명과 부서를 출력하기 위해서 수신 문서 수만큼의 쿼리가 발생한다. 현행 쿼리 SELECT org_id,userlog_name,userlog_real_name FROM igt_group WHERE userlog_id = (select userlog_id from igt_member where group_member='17140') 문제점 inner query를 사용하기 때문에 사실상 2번의 쿼리를 수행한다. 사이베이스에서는 inner query 보다는 join의 성능이 좋다고 판단된다. 조치사항 및 개선점 join 쿼리로 개선한 결과 실행 계획 상으로 2단계 쿼리가 한 단계로 줄어드는 효과 발생 SELECT g.org_id, g.userlog_name, g.userlog_real_name FROM igt_group g, igt_member m WHERE g.userlog_id = m.userlog_id AND m.group_member='17140' 5.4 게시 인덱스 튜닝 5.4.1 미열람 게시판 쿼리 가장 나은 성능 개선 효과를 가져왔음.
  • 16. Technical document 16 / 18 현행 쿼리 SELECT count(1) as bNumber FROM igt_bbs WHERE doc_regdate > '2005-01-13' and is_restrict not like 'Y' and resv_date <= getdate() and doc_bbsid in ('001','002','102','201','202','203','204','205','206','207', '208','209','301','302','303','304','401','402','403','404','501','502', '503','504','601','602','603','604','620','621','701','702', '703','704','705','99999','4200000', '4200000e' ) 문제점 idx_bbs3(doc_bbsid, resv_date, doc_regdate) 인덱스를 사용하며, doc_bbsid 수만큼 인덱스를 반복하여 읽 어들인다. 현재 운영 중인 최근 게시판 수가 38개에 달하기 때문에 상당한 부하를 유발한다. 또한 이러한 쿼리가 미열람 게시판에서 5회에 걸쳐 수행된다. (오늘 등록 게시물 열람 건수, 오늘 미열람 게시 건수, 최근 게시물 전체 건수, 사용자가 조회한 최 근 게시물 건 수, 게시물 목록 쿼리 등) 조치사항 및 개선점 idx_bbs2(doc_regdate, doc_urgency)를 사용하도록 힌트를 제공하여, 인덱스 스캔 횟수를 한번으로 감소 시킨다. 또한 최근 3일간의 게시물을 조회하기 때문에 인덱스 내부에서도 30~50개의 레코드만을 스 캔하게 됨으로써 효율이 극대화 된다. 산술적으로 38 * 5 (190)회에 걸친 인덱스 조회가 5회로 줄어든다. 또한 인덱스 조회 범위가 전체에서 1%이내로 감소함으로 잠정 효과는 약 50배 이상에 달한다. SELECT count(1) as bNumber FROM igt_bbs (index idx_bbs2) WHERE doc_regdate > '2005-01-13' and is_restrict not like 'Y' and resv_date <= getdate() and doc_bbsid in ('001','002','102','201','202','203','204','205','206','207', '208','209','301','302','303','304','401','402','403','404','501','502', '503','504','601','602','603','604','620','621','701','702', '703','704','705','99999','4200000', '4200000e' ) 6. 성능 개선 6차 6.1 작업 개요 포털, 메일 및 게시 서비스 성능 개선.
  • 17. Technical document 17 / 18 6.2 메일 및 게시 페이지 당 출력 레코드 제한 메일, 게시판 목록의 페이지 당 출력 레코드 수를 50에서 20으로 감소 6.3 포털 쿼리 튜닝 6.3.1 최근 게시 (gwTable4.html) 최근게시 목록 추출 후 개별 게시물을 조회 했는지 여부를 확인하는 쿼리와 게시판 명칭을 추출하 는 쿼리를 실행하던 방식을 개선하여, 3종의 쿼리를 단일 쿼리로 통합하고, set rowcount 5 지정 set rowcount 5 select doc_writername, doc_bbsid, doc_yearmon, doc_number, doc_subject, doc_writer, doc_regdate, writer_deptname, bbs_name from igt_bbs (index idx_bbs2), igt_bbs_catalog where doc_regdate > dateadd(dd,-3,getdate()) and doc_bbsid in (select bbs_id from igt_bbs_env where userlog_id='17140') and resv_date <= getdate() and is_restrict not like 'Y' and doc_number not in (select doc_number from igt_bbs_read where userlog_id='17140') and bbs_id = doc_bbsid order by doc_regdate desc 6.3.2 업무공지 (gwTable1.html) 최근 업무공지 목록 추출 후 개별 게시물을 조회 했는지 여부를 확인하는 쿼리를 실행하던 방식을 개선하여, 2종의 쿼리를 단일 쿼리로 통합하고, set rowcount 5 지정 set rowcount 5 select doc_subject, doc_writername, doc_yearmon, doc_number, writer_deptname, doc_regdate, doc_writer from igt_bbs (index idx_bbs2) where doc_regdate > dateadd(dd,-3,getdate()) and doc_bbsid = '102' and resv_date <= getdate() and is_restrict not like 'Y' and doc_number not in (select doc_number from igt_bbs_read where userlog_id='17140') order by doc_regdate desc 6.3.3 본부 공지 (gwTable2.html) 및 게시속보(gwMain_down.html) 위와 동일한 방식으로 튜닝 SELECT doc_bbsid, doc_subject, doc_writername, doc_yearmon, doc_number, doc_writer, doc_regdate, writer_deptname from igt_bbs (index idx_bbs2)
  • 18. Technical document 18 / 18 where doc_bbsid in ( '4200000', '4200000', '4200000e') and doc_regdate > dateadd(dd,-3,getdate()) and resv_date <= getdate() and is_restrict not like 'Y' and doc_number not in (select doc_number from igt_bbs_read where userlog_id='17140') order by doc_regdate desc select doc_bbsid, doc_subject, doc_yearmon, doc_number, doc_writer from igt_bbs (index idx_bbs2) where doc_urgency='Y' and doc_regdate > dateadd(dd,-1,getdate()) and resv_date <= getdate() and is_restrict not like 'Y' and doc_number not in (select doc_number from igt_bbs_read where userlog_id='17140') order by doc_regdate desc