전임자가 없는상태에서 유지보수를 하고 있어서
운용되고 있는사이트에 문제가 발생했을때 하나식 손보는 중인데요
아직 DB쪽에 취약점이 있어 선배님들께 질문좀 드리겠습니다
현재 로그로 사용되는 중요테이블 ( 사이트 전체 비용의 2~3번째로 많이 사용됨, 계속insert,update발생 )
에서 교착상태가 계속 발생하여 질문 드립니다.
현재 이 LOG테이블에서
SELECT (SELECT MAX(l_no) FROM [log_table] WHERE log_id ='XXXX') as 'max_no'
, l_no
, DATEDIFF(SECOND, log_edate, GETDATE()) AS 'INTERVAL_TIME'
FROM [log_table]
WHERE log_id ='XXXXX' AND log_category = 'VC12345' AND log_key = 'ABCDEABCDE'
이런식으로 조회를 해서 없으면
INSERT 하고 조건에 충족하면 UPDATE 하는 구문으로 짜여져 있는데
이 페이지는 여러사용자가 동시다발적으로 실행됩니다.
위 SELECT 문 뒤 UPDATE 구문에서
UPDATE [log_table] SET XXX=XXX WHERE log_id ='XXXXX' AND log_category = 'VC12345' AND log_key = 'ABCDEABCDE'
따로 트랜잭션을 사용하진 않고 db.execute 구문으로 사용하고 있는데 아래의 오류가 발생해서
트랜잭션(프로세스 ID 55)이 잠금 | 통신 버퍼 리소스에서 다른 프로세스와의 교착 상태가 발생하여 실행이 중지되었습니다. 트랜잭션을 다시 실행하십시오
트랜잭션구문이 없는데 이런 에러가 떠서 문제점이 파악이 안됩니다 ㅠ
혹시 SELECT시에도 테이블 전체에 LOCK이 걸리는건가요?
Q1-1. 위 UPDATE문 이전에 실행되는 SELECT 구문의 FROM 절 뒤에 WITH(NOLOCK) 에 넣으면 괜찮을까요 ?
Q1-2. MAX값 뽑기위해 서브쿼리를 사용했는데 2번의 쿼리로 실행하는게 나을까요
Q2.
위테이블에 identity 필드에만 PK가 잡혀있는데 테이블이 100만건이 넘어가 좀더 사용비용을 줄이고 싶은데
사용자가 SELECT/INSERT/UPDATE 시에는
WHERE 절에 log_id [varchar(25)], log_category [varchar(20)], log_key [varchar(10)] 3개 필드를 항상 사용하고
정렬은 사용하지 않고
관리자는 SELECT조회시 log_sdate [datetime] 으로만 정렬해서 사용을 하는데
이런경우에는 INDEX를 어떤식으로 잡아야 하나요.
제가 공부하면서 선배님들 자료 검색해서는
log_id log_category log_key 3개 필드를 복합인덱스 하는게 나은가 라고 생각하고 있습니다.
근데 이렇게 INDEX를 잡아버리면 log_sdate DESC 로 정렬했을때 속도 문제가 발생할꺼같아서
관리자쪽에서 조회시 속도가 너무 느려지지 않을까 염려됩니다
미리 답변 정말 감사드립니다!!!!!!!!!!!!!!!
DB는 정말 공부하면 할수록 더 어려운거같습니다!
1-2. 분리도 좋지만 select 결과를 사용하나요? 그게 아니면 바로 select 구문 제거하고 update 시 없으면 insert 로 해도 되겠네요,,
2. 인덱스는 위의 글만으로는 답변이 어렵겠네요,,
참고로 인덱스는 더블링크드 리스트입니다,, asc로 잡아도 desc로 사용할 수 있습니다,,,
단, 복합인덱스는 조금 다를 수 있습니다,,
자세한 답변을 원하시면 sp 전체 내용과 플랜을 같이 올려 주시면 좋을꺼 같네요,,