#title 집계부하분산 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 문법이 맞나 모르겠네요. 저장 프로시저를 사용하던지, 트리거를 사용하던지 방법이야 여러가지겠지요. '분할' 이나 '분산'의 글자가 들어가면 필연적으로 복잡해집니다. 복잡성은 돌고돌아 비용상승의 결과를 가져다줍니다. 웬만하면 잘 설득해서 서버자원을 늘리시는게 누이 좋고 매부 좋을 것 같습니다. 사람은 복불복이지만 하드웨어는 거짓말을 안하거든요. }}}