반응형

튜닝도 거치고 쿼리분석기에서 예상실행계획상 누락된 인덱스도 없으며 0.1초만에 잘 나오는 쿼리상으론 아무 문제 없는 쿼리임에도 불구하고 웹페이지에서 실행하면 15초씩 걸리는 이상한 현상이 발견되었다.


가만히 놔둬선 안되겠다 싶어 구글링을 해보니 나와 같은 증상을 겪은 사람들이 이미 여럿 존재함을 확인할 수 있었다.

이유는 ARITHABOART 이녀석 때문인데 시퀄서버에선 기본값이 ON이지만 ADO에선 아래 표처럼 기본값이 OFF


결론은 쿼리 날릴 때 ADODB의 설정을 건드려주면 된다.
Static Query인 경우엔 쿼리문 앞에 SET ARITHABORT ON을 넣어주고
Set objCmd = Server.CreateObject("ADODB.Command")
    SQL = ""
    SQL = SQL & vbCrLf & "SET ARITHABORT ON"
    SQL = SQL & vbCrLf & "SELECT"
    ......
    With objCmd
    .ActiveConnection = dbConn
    .CommandType = adCmdText
    .CommandText = SQL
    
               .Parameters.Append .CreateParameter("param", adDate, adParamInput, , paramdata)
    End With
    
    Set rs = Server.CreateObject("ADODB.RecordSet")
    rs.CursorLocation = adUseClient
    rs.Open objCmd, , adOpenStatic, adLockReadOnly

    If rs.EOF Then
    Else
    End If

    rs.Close
    Set rs = Nothing
Set objCmd = Nothing

Stored Procedure인 경우
SqlConnection dbConn = new SqlConnection(strConnection);

dbConn.Open();
SqlCommand cmdAritabort = new SqlCommand("SET ARITHABORT ON", dbConn);
cmdAritabort.ExecuteNonQuery();
           
SqlCommand cmd = new SqlCommand("dbo.usp_example", dbConn);
cmd.CommandType = CommandType.StoredProcedure;

SqlDataAdapter adapter = new SqlDataAdapter(com);
adapter.Fill(table);

dbConn.Close();


관련하여 더 자세히 느끼고 싶다면 Slow in the Application, Fast in SSMS? Understanding Performance Mysteries란 버거형님의 진중하고 장대한 글을 참고해보길 바란다.
https://www.sommarskog.se/query-plan-mysteries.html
해당 글에선 좀 다르게 이야기 해주던데 너~~~무 길고 난 ARITHABOART ON 설정으로 느린 쿼리를 해결하였으므로 이쯤에서 만족하려 한다.

반응형
Posted by Hippalus

댓글을 달아 주세요

반응형

웹개발을 하다보면 속도가 느려 사용을 못할 쿼리를 짜게 되기도 한다.
DB설계란게 다 그렇듯 최종 완성물로 가기까지 계속 설계가 변경되기도 하고 설령 완료되어 운영하더라도 기능 변경 요구나 데이터가 쌓여감에 따라 초기 설계와 달라지거나 속도가 느려지는 일들이 비일비재 하므로 그때마다 DBA에게 위탁하기도 뭐하고..
작은 회사에선 DBA가 있을턱도 없고 그렇다고 느린 속도를 한탄만 하고 있을 순 없는데
MSSQL에선 기특하게도 디비 튜닝을 매우 쉽게 도와주는 기능을 기본 탑재하고 있다.

초보자도 쉽게 튜닝이 가능하므로 따라해보자

1. 시퀄(mssql을 있어 보이게 발음해보자) Management Studio을 실행 후  문제가 되는 쿼리창에 복사해 두자.
2. Management Studio의 상단 메뉴에 보면 예상실행계획 표시라는 아이콘이 보일것이다. 
네모 세개가 선으로 이어지고 거기에 삼각형이 뒤집어진 아이콘인데 실행 버튼 우측에 조금만 가면 있다.
모르겠으면 단축키로 Ctrl + L을 누르면 된다.

3. 쿼리가 실행되고 나면 하단 쿼리 결과 우측에 보면 요런 ... 네모 버튼이 보일것이다.
여기에서 마우스 우측 버튼을 누르면 컨텍스트 메뉴가 나타난다.

누락된 인덱스 세부 정보(M)을 마우스 왼쪽 버튼으로 누르면

 새 쿼리창이 뜨면서 아래처럼 주석안에 누락된 인덱스를 친절히 알려준다.
/* 주석안의 */ CREATE INDEX문에서 대괄호 [] 안의 인덱스 이름을 지정해주고 실행만 시켜주면 튜닝에 필요한 적합한 인덱스가 나타난다.
<NAME OF MISSING INDEX, SYSNAME, > 이부분을 원하는 인덱스 명으로 바꿔주면 된다.
내 경우 IDX_TABLENAME_FIELD 명을 규칙으로 정해서 알맞게 바꿔주고 있다.

5. 다시 2번을 눌러서 4번까지 반복해가며 속도가 빨라질 때까지 진행하면 된다.


조건문에 따라 쿼리문이 달라지기 때문에 그에 맞게끔 쿼리를 변경해가며 수행해야 할 수도 있다.
또 인덱스를 추가만 한다고 모든 경우에 다 맞아 떨어지리란 보장 또한 없다.
경우에 따라선 설계 자체를 변경해야 할 수도 있고 쿼리 자체를 바꿔야 할수도 있지만
경험상 상당수 속도 개선 효과를 볼 수 있었다.

 

 

반응형
Posted by Hippalus

댓글을 달아 주세요

반응형

회사에서 월별 음력, 양력과 관련된 공지를 하게 되었고 기준 데이터가 어떤 데이터는 음력, 어떤 데이터는 양력을 사용하고 있는 상황이다.

MSSQL에 음력, 양력 데이터 등록시 변환을 하든 조회 시점에서 해당하는 레코드들을 조회하든 음력과 양력 사이에서 실시간 변환보단 매핑 테이블을 이용하여 조회할 경우 더 효율적이란 판단된다.





왜 CHAR(10)가 아닌 VARCHAR(10로 설계했느냐 묻는다면


어차피 CHAR(10)이든 VARCHAR(10)이든 차지하는 공간은 동일하기 때문이다.

MSSQL에서 VARCHAR 자료형의 경우 포인터 형태로 존재하므로 데이터 수정이 발생될 경우 성능저하가 발생할 수 있겠으나 이처럼 매핑 테이블인 경우 데이터는 불변이다.

또 반대로 데이터 유형 역시 YYYY-MM-DD 고정 자릿수 이므로 CHAR(10)로 설계해도 상관없다.

즉 VARCHAR이든 CHAR이든 마음대로 해도 된다.





주의할 점은 음력 데이터 중 1985-02-30처럼 2월 30일 데이터가 존재한다란 점이다.

이는 테이블 설계시 DATETIME을 사용할 수 없으므로 테이블 설계시 VARCHAR(10)로 설계해야 정상 반입 및 이용이 가능하다.



끝으로 실제 사용하는 예시


현재월을 기준으로 하려면 그냥 getdate()로 바꾸면 됨


SELECT DATEADD(day, -1,DATEADD(MONTH, 1,DATENAME(YEAR,getdate()) + DATENAME(month,getdate())+'01'))




첨부파일로 데이터까지 올리려다가....


다 쓰고 올리려 했더니 데이터 용량 때문에 못올림 ㅜㅜ

필요하신 분은 연락주시면 개별적으로 드리겠습니다.


반응형
Posted by Hippalus

댓글을 달아 주세요