_대문 | 방명록 | 최근글 | 홈피소개 | 주인놈 |
FrontPage › 집계부하분산
|
|
http://www.sqler.com/?document_srl=505251&mid=bSQLQA&comment_srl=505567&rnd=505567#comment_505567
문제점 사용자에게 10~20초안에 결과를 보여주고 싶은데 10분~20분정도 소요됨 (데이터가 일별 2500만건정도 있음) (전체 데이터 225억건) 스키마 날짜 varchar(8) 매장 varchar(10) 매출번호 bigint 금액 int 인덱스 - 클러스터드 유닉크 날짜, 매장, 매출번호 SELECT 매장 , COUNT(*) AS 개수 , SUM(금액) AS 합계금액 FROM 매출 (클러스터드 인텍스) WHERE 날짜 = '20110724' GROUP BY 매장 -- select 되는 건 2500만건 사전내용 1.인덱스 2.서버 스팩은 바꿀 수 없음. 3.MS-SQL SERVER 2005 사용 해본 내용 1. (매출테이블을) 미리 계산하여 생성한 테이블(집계테이블) 사용 - 매출테이블의 데이터가 바뀌면(삽입, 수정, 삭제) 데이터가 틀어짐 - 집계하는 과정에서는 서버의 많은 자원을 사용 2. 테이블 불리 - 효과는 있으나, 기존 데이터를 사용자에게 보여주기 어려움 서버를 바꿀 수도 없고... 바꾼다고 해도 나중에 더 많은 데이터가 들어오면... 소용 없을꺼 같고요... 쿼리로는 최적화가 더 없는거 같은데요... 좋은 개념이나 방법이 없을까요? 나의 답변은..
'집계할 때'는 이미 부하집중입니다. 집계 테이블의 소스는 매출 테이블입니다. 변화는 매출 테이블이 겪습니다. 당연히 매출 테이블에 종속성이 있는 집계 테이블도 변경되어야 합니다. 집계 테이블은 매출 테이블의 스냅샷이라고 볼 수 있습니다. 그러므로 집계 이후의 변경분을 스냅샷에 적용시켜주려면 재집계 하던가 변경된 부분만을 갱신해야겠지요. 이런 경우의 부하분산 솔루션은 단순합니다. 매출 테이블이 변경될 때 집계 테이블도 변경하면 되겠습니다. (distinct count 같은게 없으니..) 간단히 예를 들면, --입력할 때 begin tran update 매출집계 set 금액 = 금액 + 1000 where 일자 = '20120101' and 매장 = 'A매장' if @@rowcount = 0 insert 매출집계 values('20120101', 'A매장', 1000) insert 매출 values('20120101', 'A매장', 1000) commit --갱신할 때 begin tran update 매출 set 금액 = 금액 - 5000 where 일자 = '20120101' and 매장 = 'A매장' update 매출집계 set 매출 = 매출 - 5000 where 일자 = '20120101' and 매장 = 'A매장' commit --삭제할 때 begin tran declare @amt int select @amt = sum(금액) from 매출 where 일자 = '20120101' and 매장 = 'A매장' delete from 매출 where 일자 = '20120101' and 매장 = 'A매장' update 매출집계 set 매출 = 매출 - @amt where 일자 = '20120101' and 매장 = 'A매장' commit 문법이 맞나 모르겠네요. 저장 프로시저를 사용하던지, 트리거를 사용하던지 방법이야 여러가지겠지요. '분할' 이나 '분산'의 글자가 들어가면 필연적으로 복잡해집니다. 복잡성은 돌고돌아 비용상승의 결과를 가져다줍니다. 웬만하면 잘 설득해서 서버자원을 늘리시는게 누이 좋고 매부 좋을 것 같습니다. 사람은 복불복이지만 하드웨어는 거짓말을 안하거든요.
|
네 마음 안에서 구하라 마음 밖에서 구하면 천년을 구해도 허사다. (부처님) |