제가 지금 일하는 곳에서 각 그룹마다 DB를 생성하여 내역들을 저장하고 있습니다.
DB서버는 총 4개이며 총800개의 DB가 분산되어 있습니다.
내역을 불러올때 각각의 DB마다 3개의 테이블을 SELECT 하여 불러옵니다.
현재는 800개의 정보를 모두 불러오면 5~15분정도 소요가 되는데 개선 방법을 알 고 싶습니다.
각각의 쿼리를 불러오는 방법은 다음과 같습니다.
php에서 각각의 DB를 로드하며 아래의 쿼리를 실행시키고 DB연결을 닫습니다.
select SUM(cnt) as 'count'
from (
select count(*) as cnt
from TB_MIS_LOG
where CONVERT(VARCHAR(10),regdate,21) between '조회한 달의 1일' and '조회한 달의 마지막일'
union all
select count(*) as cnt
from TB_HZ_MIS_LOG
where CONVERT(VARCHAR(10),regdate,21) between '20".$y."-".$m."-01' and '조회한 달의 마지막일'
union all
SELECT count(*) as cnt
FROM tb_mov_log
where CONVERT(VARCHAR(10),start_time,21) between '20".$y."-".$m."-01' and '조회한 달의 마지막일'
) list
Comment 14
-
이리
2016.07.05 12:04
-
쭈스비
2016.07.05 13:56
그러면 reg_date, start_time 컬럼이 인덱스에 잇으면 되는건가요?
-
이리
2016.07.05 14:29
regdate와 start_time 자료형이 DATETIME인가요?
인덱스가 없으시면 인덱스 잡고
WHERE regdate BETWEEN '2016-06-01 00:00:00' AND '2016-06-30 23:59:59'
이런식으로 사용하시면 seek가 되서 성능이 개선될 듯 합니다.
-
쭈스비
2016.07.05 17:49
네 DATETIME입니다.
인덱스를 잡고싶은데 DB개수만 800개가 넘어서 인덱스 작업하려면 몇일은 소요될듯 하네요 ㅜㅜ
(보시는 쿼리의 테이블은 800개의 DB에 모두 저장되어 있어 일단은 그부분부터 수정할 수 있도록 해야겠네요) -
minsouk
2016.07.05 13:22
Async 쿼리를 만들면 10초 이내로 응답을 구할 수 있을듯 하네요, 이리님이 말씀하신 where 조건 필터는 선행 되어야 할 듯 하구요
Async Multi Thread 쿼리는 CLR 로 작성할 수 있습니다.
-
쭈스비
2016.07.05 13:57
Async가 뭐죠? 처음들어 보네요 일단은 찾아보고 추가로 질문 수정하겠습니다.
-
항해자™
2016.07.05 18:25
800 개의 디비에 비동기로 쿼리하는 것을 말합니다,,
php에서 멀티 스레드가 되는지 모르겠네요,, -
쭈스비
2016.07.05 18:38
알려주셔서 감사합니다.
php는 스레드라는 개념자체가 없어서 더 고민입니다 ㅜㅜ
-
항해자™
2016.07.05 19:28
ajax로 처리하는 방법도 있습니다,, -
쭈스비
2016.07.06 09:32
네 저도 첨에는 Ajax고민했었는데 그걸로 해도 속도는 변함없을것 같더라구요 ㅜㅜ
-
항해자™
2016.07.07 19:20
ajax로 거의 동시에 800개 디비에 던질 수 있을꺼 같은데요,, -
쭈스비
2016.07.06 09:35
답변달아주신분들 모두 감사합니다 ^^
800개가 넘는 DB를 php에서 하나하나연결하다보니 속도가 빨라질 수가 없더군요...
(연결 1개당 0.1초 걸려도 80초가 걸린다는...)
결국은 스케쥴로 통계테이블 하나 만들어서 넣어뒀네요 ㅜㅜ -
가경승민아빠
2016.07.06 12:58
한개의 DB 서버에서 나머지 서버로 링크 시켜 조회하여 결과를 가지고 오면 어떨까요???
그렇게 하시면, PHP에서는 한개의 DB 서버를 보고, 그 DB 서버에 나머지 DB서버의 데이터를 조회하여 가지고 오는 방식으로요.
그리고, Where 절에서 조건이 거의 같다면 변수등을 활용하여 보시는 건 어떨까요?
-
쭈스비
2016.07.06 18:26
음... 생각해보니 프로시저 사용을 좀 해보는것도 나쁘지 않을것 같아 보이네요
실행계획을 올려주시면 고수분들이 잘 봐주실겁니다.
쿼리문만 봐서는 WHERE절에서 regdate, start_time 컬럼을 가공함으로 인해 컬럼에 인덱스가 있어도 seek가 안되고 scan이 될 거 같습니다.