삽질의 현장/- DataBase

[삽잡이::DB] Index를 타라~

shovelman 2016. 10. 5. 00:08


인덱스는 '색인'을 뜻합니다.

 

(출처_ 네이버 백과사전)


DB에서는 수 없이 많은 데이터속에서 빠르게 검색하기 위해 '인덱스'를 사용하게 됩니다.

인덱스란, 원하는 데이터를 쉽게 찾을 수 있게 도와주는 녀석이라는 것입니다.

제 주변에서는 흔히들 '인덱스를 타다'라고들 하더군요..


오빠 차 뽑았다~ 널 데리러 가~


아무튼, 우리가 만들어놓은 DB 테이블을 기반으로 인덱스를 생성할 수 있습니다.


모든 DBMS는 B*Tree 인덱스를 기본적으로 제공한다고 합니다.

(출처_ dbguide.net)


나무를 뿌리부터 거꾸로 세워둔 형태의 구조입니다.

어지럽겠다~~ 


가지역할을 수행하는 Branch Block은 나무와 같이 분기를 목적으로 사용되고,

가지에 달려있는 잎사귀와 같은 Leaf Block을 가리키는 포인터를 가지고 있습니다.


Leaf Block는 인덱스 키값과 ROIWD 라고 불리는 주소 정보를 가지고 있습니다.

이 ROIWD는 키값에 해당하는 테이블 레코드를 찾아가는 정보가 있지요.


인덱스를 생성할 때에는 동일한 컬럼으로 구성된 인덱스는 생성할 수 없으며,

컬럼의 순서가 다르면 서로 다른 인덱스를 생성할 수 있는 특징을 가지고 있습니다.

또한, 인덱스 컬럼의 순서에 따라 성능에 영향이 있을 수 있습니다.


우리는 데이터를 추출하기위해 Query문을 작성합니다.

추출하기 위한 Query문에는 검색 조건들이 덕지 덕지 붙어있겠지요.


제가 만든 이런 더러운 Query문은

'optimizer'라는 녀석이 최적의 실행항법을 결정해줍니다.


반가워 옵티마이저~~ 옵티머스 프라임같아~~ 



ㅎㄷㄷ...


그런데, 요즘 느끼는 생각이지만 Query문도 아름답게 잘 짜야합니다...

(이걸 왜 지금 알았을까...)

왜냐, 인덱스를 잘 타지 못하고 '전체 테이블 스캔' 방식을 

옵티마이저님이 선택하실 수도 있기 때문입니다.


아무튼... Full Scan이라 하는 '테이블 전체 스캔' 방식의 경우

데이터를 검색할 때 테이블에 존재하는 모든 블록의 데이터를 읽게됩니다.

즉, 오래걸린다 이겁니다.

물론, 필요한 경우 모든 블록을 읽어야할 경우도 있으니 무조건 나쁘다는 것은 아닙니다.


테이블 전체 스캔방식 외에도 '인덱스 스캔' 방식으로 Query를 날릴 수도 있습니다.

'인덱스 스캔'방식은 인덱스를 구성하는 컬럼의 값을 기반으로 데이터를 추출하는 방식입니다.

그 만큼 속도가 나겠지요.


효율적인 인덱스 사용을 통해 테이터를 검색하기 위해서는

인덱스 스캔범위를 최소화시켜야할 것입니다.

이를 위해서는 등치(=) 조건으로 비교를 하는 방향으로 Query문을 작성하는 것이 좋습니다.

만약, 이와 같은 조건이 힘들다면

되도록 뒷쪽 컬럼에서 사용되도록 작성하는 것이 좋습니다.

또한, 범위 조건을 2개 이상 사용하지 않는 것이 바람직합니다.


정리해보겠습니다.


정리를 하며 머리에 쏙쏙~ 


소위 말하는 '인덱스를 타기위해서'는 

인덱스 선두 컬럼이 조건절에 반드시 사용되어야합니다.

따라서, 인덱스를 구성할 때에는 조건절에 항상 사용되거나, 

자주 사용되는 컬럼으로 선정해야하는 것입니다.


또한, 등치(=) 조건으로 자주 조회되는 컬럼을 앞쪽에 두어야합니다.

해당 조건으로 비교를 하게 되면, 읽고 버리는 레코드가 없기에

스캔 단계에서 효율성이 우수해지기 때문입니다.


조건절에 사용되지 않은 컬럼일지라도

정렬 연산을 대체할 목적으로 (order by, group by를 위한 정렬 연산)

인덱스 구성에 포함시키는 방법도 인덱스 설계에 바람직한 접근 방법이 될 수 있습니다.

이를 위해서는 인덱스 컬럼 구성과 같은 순서로 누락 없이 order by절에 기술해주어야한다고 합니다.


인덱스를 스캔하며 테이블을 엑세스하는 양이 도를 넘어 많아지게 되면,

Full Scan보다 느려질 수 있기 때문에

조건절에서 어떤 형태로 자주 사용되는지, 사용빈도 등

어떤 쪽이 효용성이 높을지 생각해봐야합니다.


이외에도, 쿼리 수행빈도, 업무상 중요도, 데이터량, 저장 공간, 인덱스 관리 비용

전략을 잘 짜서 Query를 작성해봅시다.


저는 공부중이지만... 너무 어려운것 같습니다... 


 으아아~ 어렵지만 즐겨야해~~