SQL/데이터 베이스 기초

sql 튜닝 / 튜닝을 위한 21가지 규칙 / 튜닝 가이드 / 더 빠른 데이터베이스 쿼리(3/3)

삐뚤어진 개발자 2019. 12. 26.

sql 튜닝 1편

 

sql 튜닝 / 튜닝에 도움 되는 21가지 규칙 / 튜닝 가이드 / 더 빠른 데이터베이스 쿼리(1/3)

데이터 베이스의 데이터들을 효율적으로 관리하려면 최적화된 쿼리가 필수적일 것이다. 데이터 베이스의 효율성을 위해 쿼리 속도가 빨라지는 SQL 쿼리 튜닝을 고려해 볼수 있다. SQL 개발자와 DBA 모두 이런 목표..

taewooblog.tistory.com

sql 튜닝 2편

 

sql 튜닝 / 튜닝을 위한 21가지 규칙 / 튜닝 가이드 / 더 빠른 데이터베이스 쿼리(2/3)

sql 튜닝 / 튜닝에 도움 되는 21가지 규칙 / 튜닝 가이드 / 더 빠른 데이터베이스 쿼리(1/3) sql 튜닝 / 튜닝에 도움 되는 21가지 규칙 / 튜닝 가이드 / 더 빠른 데이터베이스 쿼리(1/3) 데이터 베이스의 데이터들..

taewooblog.tistory.com

 

 

 

15. 트리거(Trigger) 사용을 자제하라
트리거 사용은 유사한 문제를 야기할 수 있다. 왜냐하면 당신이 시도하고 있는 어떤 동작이 원래의 작업과 동일한 거래에서 수행될 것이기 때문이다. 이는 트리거가 완료될 때까지 여러 테이블을 잠글 수 있다는 것을 의미한다. 이러한 트리거를 개별 트랜잭션으로 분할하면 리소스가 적게 잠기므로 필요할 경우 변경 사항을 복원하기가 더 쉬워진다. 가능한 경우 트리거하지 마십시오.

 


16. GUID에 대한 클러스터링을 피하라
GUID(Globally Unique Identifier)를 사용하여 테이블 데이터를 정렬하지 마십시오. 무작위로 생성된 이 16비트 숫자는 사용자 테이블을 훨씬 더 빨리 조각낸다. 날짜와 IDENTIFY와 같은 값을 점진적으로 증가시켜 데이터를 분류하는 것이 훨씬 좋다. 이 규칙은 모든 휘발성 열에 적용된다. 테이블은 단 몇 분 만에 극적으로 조각날 수 있다.

 


17. 테이블에 있는 모든 것을 카운트(Count)하지 말라
테이블에 데이터가 존재하거나 어떤 고객에 대한 데이터가 존재하는 지를 확인할 필요가 있으며, 확인 결과에 따라, 어떤 조치를 취해야 한다고 가정하자.

필자는 그런 데이터의 존재를 확인하기 위해 누군가가 SELECT COUNT(*) FROM dbo.T1 명령을 실행하는 것을 자주 보았다.

SET @CT = (SELECT COUNT(*) FROM dbo.T1);
If @CT > 0
BEGIN <Do something>
END

전혀 불필요한 명령이다. 존재 여부를 확인하고 싶다면, 다음과 같이 하라:

If EXISTS (SELECT 1 FROM dbo.T1)
BEGIN
<Do something>
END

다른 말로 하면, 테이블에 있는 모든 것을 카운트하지 말라는 것이다. 첫 번째 행으로 돌아가면 찾을 수 있다. SQL 서버는 EXIST 문을 제대로 사용할 수 있을 정도로 똑똑하며, 두 번째 블록의 코드는 아주 빠르게 결과를 돌려준다. 테이블이 크면 클수록, 더 많은 차이를 낼 것이다.

18. 행을 카운트하려면 시스템 테이블(System Table)을 사용하라
커다란 테이블의 행을 정말로 카운트할 필요가 있다면, 시스템 테이블에서 끌어 올 수 있다. ‘SELECT rows from sysindex’ 명령문은 모든 인덱스에 대한 열의 수를 알려줄 것이다.

그리고 클러스터된 인덱스가 데이터 자체를 나타내기 때문에, ‘WHERE indid = 1’을 추가하면 테이블 행을 얻을 수 있다. 그 다음에는 그냥 테이블 이름을 추가하기만 하면 만사형통이다. 이렇게 하면, 최종 쿼리는 다음과 같다

SELECT rows FROM sysindexes WHERE object_name(id) = ‘T1’ AND indexid = 1

19. 필요한 수의 열만 끌어오라
모든 쿼리를 개별적으로 열을 나열하는 대신 SELECT * 문으로 코딩하는 것은 너무 쉽다. 다시, 문제는 그것이 필요로 하는 것보다 더 많은 데이터를 가져온다는 것이다. 개발자는 120개의 열과 수백만 개의 행이 있는 테이블에서 SELECT *를 실행했지만 3~5개의 행만 사용하였다. 그 시점에서는 개발자들이 필요한 것보다 훨씬 더 많은 데이터를 처리할 뿐만 아니라 다른 공정에서 자원을 가져갔다.



20. 네거티브 검색(Negative Search)를 피하기 위해 쿼리를 재 작성하라
인덱스를 사용할 수 없는 쿼리를 사용해서 데이터를 행 별로 비교할 필요가 있을 때, 예를 들어 FROM Customers WHERE RegionID <> 3 같은 경우는 인덱스를 사용할 수 있도록 쿼리를 재작성하는 것이 더 낫다.

SELECT * FROM Customers WHERE RegionID < 3 UNION ALL SELECT * FROM Customers WHERE RegionID

데이터 세트가 큰 경우, 인덱스를 사용하는 것이 테이블 스캔 버전을 크게 능가하는 결과를 내 놓을 수도 있다. 물론, 더 열악한 결과를 낼 수도 있으니 구현에 앞서 시험해보라.

필자는 이 쿼리가 팁 13번(중복 처리를 피하라)을 어긴다는 것을 알았지만, 융통성 없는 규칙은 없다는 것을 보여주는 것이기도 하다. 여기서는 중복 처리를 했지만, 대가가 큰 테이블 스캔을 피하기 위해서이다.


21. 맹목적으로 코드를 재사용하지 말라
필요한 데이터를 얻고 있다는 것을 알기 때문에 다른 사람의 코드를 복사하는 것은 쉽다. 문제는 필요한 것보다 훨씬 더 많은 데이터를 가져오는 경우가 많고, 개발자들은 그 양을 줄이려고 거의 노력하지 않아 엄청난 데이터 집합으로 이어진다. 이것은 일반적으로 추가 외부 결합 또는 WHERE 문에서 추가 조건의 형태로 나타난다. 재사용 코드를 필요한 수준으로 줄일 수 있다면 상당한 성능 이점을 볼 수 있을 것이다.

이 모든 기술들이 모든 상황에서 효과가 있는 것은 아니라는 것을 기억하라. 어떤 기술이 가장 효과가 좋은지 실험해 봐야 할 것이다. 그러나 일반적으로 언급되는 SQL 팁을 잘 사용하면 DBA에서 최종 사용자에 이르기까지 동시성을 높이고 성능을 가속화하며 모든 사람의 생활을 훨씬 쉽게 할 수 있다.





마지막으로, 앞에서 말했듯이 데이터베이스(RDBMS)의 종류는 SQL Server(MS-SQL), Oracle(Oracle), DB2, Sybase, MySQL 등이다. 지나치게 많아요. 물론 여러 가지 사물의 특성이 다르고 내부 논리가 다 다를 것이다.



위의 내용은 일반적인 특징의 개념에 불과하며, dbms를 정말로 최적화하려면 사용하고 있는 RDBMS의 특성을 정확히 파악하고 내부 논리를 사용하는 것이 중요하다.

 

댓글