대부분의 개발자가하는 것처럼 (주로 ... 음! 인덱스) 인덱스를 사용하지만 인덱스를 사용하여 데이터베이스를 최적화하는 미묘한 방법이 많이 있습니다. DBMS 구현과 관련이 있는지 확실하지 않습니다.
내 질문은 : 인덱스를 사용하는 방법에 대한 좋은 예는 무엇입니까 (기본, 명백한 경우 제외), 테이블에서 인덱스를 지정할 때 DBMS가 데이터베이스를 어떻게 최적화합니까?
대부분의 개발자가하는 것처럼 (주로 ... 음! 인덱스) 인덱스를 사용하지만 인덱스를 사용하여 데이터베이스를 최적화하는 미묘한 방법이 많이 있습니다. DBMS 구현과 관련이 있는지 확실하지 않습니다.
내 질문은 : 인덱스를 사용하는 방법에 대한 좋은 예는 무엇입니까 (기본, 명백한 경우 제외), 테이블에서 인덱스를 지정할 때 DBMS가 데이터베이스를 어떻게 최적화합니까?
답변:
색인을 "목차"로 생각하십시오. 이것은 파일의 위치에 대한 포인터 목록 (일명 오프셋)입니다. 일치하는 기준에 대해 테이블을 검색하는 대신 테이블에 수백만 개의 레코드가 저장되어 있다고 가정하면 일치하는 순서로 정렬 된 목록을 참조한 다음 포인터를 특정 일치하는 행에 스택하는 것이 훨씬 빠릅니다. 인덱스의 완벽한 예는 테이블 기본 키 필드, 가장 일반적으로 "id"필드입니다. 행 ID # 11234566을 원하는 경우 위치 11234566에 대한 데이터 소스를 스캔하는 것보다 인덱스에 데이터에 대한 포인터를 요청하는 것이 훨씬 빠릅니다.
인덱싱을 그렇게 명확하게 사용하지는 않습니다.
CREATE TABLE activity_log (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
activity_type_id SMALLINT UNSIGNED NOT NULL,
datetime_created DATETIME
KEY(activity_type_id),
PRIMARY KEY(id)
);
CREATE TABLE activity_log_to_date_key (
activity_log_id INT UNSIGNED NOT NULL,
date_created_key INT UNSIGNED NOT NULL REFERENCES dim_datetime(id),
UNIQUE KEY(activity_log_id),
KEY(date_created_key)
);
CREATE TABLE dim_datetime (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
date_hour DATETIME NOT NULL,
PRIMARY KEY(id),
KEY(date_hour)
);
작업을 수행하면 로그 레코드가 생성되지만 로그 테이블보다 검색 / 정렬이 더 빠른 인덱스 된 날짜 시간에 대한 참조를 만들 수 있습니다. 그런 다음 고유 한 기본 키로 로그 테이블을 다시 결합하십시오. 이것을 확장해야한다면 알려주십시오. 이것이 의미가 있기를 바랍니다.
샘플 쿼리 :
SELECT a.activity_log_id, al.activity_type_id, al.datetime_created
FROM activity_log_to_date_key a
INNER JOIN dim_datetime d ON (d.id = a.date_created_key)
LEFT JOIN activity_log al ON (al.id = a.activity_log_id)
WHERE d.date_hour BETWEEN '2009-01-01 00:00:00' AND '2009-06-01 12:00:00';
많은 사람들이 놓친 것처럼 보이는 한 가지 점은 DBMS가 쿼리에서 테이블 참조 당 하나의 인덱스 만 사용하는 경우가 많거나 가능할 수 있다는 것입니다. 여러 인덱스를 사용할 수 있고 사용하는 경우 결합 된 데이터를 사용하는 것이 더 빠를 것입니다 존재하는 경우 색인.
예를 들어, 큰 테이블에서 행을 검색하는 경우 WHERE AnIntegerColumn = 42 AND AnOtherInt = 69
해당 행으로 가장 빠른 경로는 AnIntegerColumn 및 AnOtherInt라는 두 열의 인덱스입니다. 각각의 인덱스 만 있고 결합 된 인덱스는없는 경우 DB는 하나 또는 다른 인덱스를 검색하고 결과를 두 번째 절로 개별적으로 필터링하거나 두 가지를 모두 스캔 한 후 결과를 결합합니다.
복합 인덱스를 사용하여 개선 할 수있는 또 다른 일반적인 간단한 작업은 WHERE SomeColumn = <SomeValue> ORDER BY SomeOtherColumn
SomeColumn 및 SomeOtherColumn에 인덱스가있는 경우 (올바른 순서로) 필터링 및 순서 지정 작업을 일부 상황에서 동시에 수행 할 수 있습니다.
인덱스를 저장하는 데 사용되는 추가 공간 (및 DB에서 쓰기 작업이 많은 경우 인덱스를 유지하기위한 IO로드)이 약간 덜 최적화 된 읽기 쿼리보다 더 나쁜 문제 일 수 있으므로 너무 많은 인덱스를 추가하면 물론 최적화가 좋지 않을 수 있습니다. 과도하게하지 마십시오.
내가 아직 여기에 언급하지 않은 것은 하나 이상의 디스크가있을 때 데이터가 실제로있는 곳과 다른 디스크에 색인을 넣고 싶을 것입니다. 일부 작업 속도가 빨라질 수 있습니다. 나는 이것이 그 자체로 의문의 가치가 있다고 생각합니다.