SQL Server 및 Oracle과 협력합니다. 일부 예외가있을 수 있지만 해당 플랫폼의 경우 일반적으로 데이터와 인덱스가 동시에 업데이트됩니다.
트랜잭션을 소유하는 세션과 다른 세션에 대해 인덱스가 업데이트되는 시점을 구분하는 것이 도움이 될 것이라고 생각합니다. 기본적으로 다른 세션에는 트랜잭션이 커밋 될 때까지 업데이트 된 인덱스가 표시되지 않습니다. 그러나 트랜잭션을 소유 한 세션은 즉시 업데이트 된 인덱스를 보게됩니다.
그것에 대해 생각하는 한 가지 방법은 기본 키가있는 테이블을 고려하십시오. SQL Server 및 Oracle에서는 인덱스로 구현됩니다. 대부분의 경우 INSERT
기본 키를 위반하는 작업이 수행 되면 즉시 오류가 발생하기 를 원합니다. 이를 위해서는 데이터와 동시에 인덱스를 업데이트해야합니다. Postgres와 같은 다른 플랫폼에서는 트랜잭션이 커밋 될 때만 검사되는 지연 제약 조건을 허용합니다.
다음은 일반적인 사례를 보여주는 빠른 Oracle 데모입니다.
CREATE TABLE X_TABLE (PK INT NULL, PRIMARY KEY (PK));
INSERT INTO X_TABLE VALUES (1);
INSERT INTO X_TABLE VALUES (1); -- no commit
두 번째 INSERT
문은 오류를 발생시킵니다.
SQL 오류 : ORA-00001 : 고유 제약 조건 (XXXXXX.SYS_C00384850) 위반
00001.
00000- "고유 제한 조건 (% s. % s)을 위반했습니다"
* 원인 : UPDATE 또는 INSERT 문이 중복 키를 삽입하려고했습니다. DBMS MAC 모드로 구성된 Trusted Oracle의 경우 중복 항목이 다른 레벨에 존재하면이 메시지가 표시 될 수 있습니다.
* 조치 : 고유 제한을 제거하거나 키를 삽입하지 마십시오.
아래의 인덱스 업데이트 작업을 보려면 SQL Server의 간단한 데모입니다. 먼저 행에 백만 개의 행과 비 클러스터형 인덱스가있는 두 개의 열 테이블을 만듭니다 VAL
.
DROP TABLE IF EXISTS X_TABLE_IX;
CREATE TABLE X_TABLE_IX (
ID INT NOT NULL,
VAL VARCHAR(10) NOT NULL
PRIMARY KEY (ID)
);
CREATE INDEX X_INDEX ON X_TABLE_IX (VAL);
-- insert one million rows with N from 1 to 1000000
INSERT INTO X_TABLE_IX
SELECT N, N FROM dbo.Getnums(1000000);
인덱스는 해당 쿼리에 대한 포함 인덱스이므로 다음 쿼리는 비 클러스터형 인덱스를 사용할 수 있습니다. 여기에는 실행에 필요한 모든 데이터가 포함됩니다. 예상대로 리턴 값이 리턴되지 않습니다.
SELECT *
FROM X_TABLE_IX
WHERE VAL = 'A';
이제 트랜잭션을 시작 VAL
하고 테이블의 거의 모든 행에 대해 업데이트하겠습니다 .
BEGIN TRANSACTION
UPDATE X_TABLE_IX
SET VAL = 'A'
WHERE ID <> 1;
이에 대한 쿼리 계획의 일부는 다음과 같습니다.
빨간색 원은 비 클러스터형 인덱스에 대한 업데이트입니다. 파란색 원은 클러스터 된 인덱스에 대한 업데이트이며 기본적으로 테이블의 데이터입니다. 트랜잭션이 커밋되지 않았더라도 쿼리 실행의 일부로 데이터와 인덱스가 업데이트되는 것을 볼 수 있습니다. 다른 요인과 함께 관련된 데이터의 크기에 따라 계획에서 항상 이것을 볼 수는 없습니다.
트랜잭션이 여전히 커밋되지 않은 상태 SELECT
에서 위 의 쿼리를 다시 살펴 보겠습니다 .
SELECT *
FROM X_TABLE_IX
WHERE VAL = 'A';
쿼리 최적화 프로그램은 여전히 인덱스를 사용할 수 있으며 이번에는 999999 개의 행이 반환 될 것으로 예상합니다. 쿼리를 실행하면 예상 결과가 반환됩니다.
그것은 간단한 데모 였지만 희망적으로 조금 정리했습니다.
제쳐두고, 나는 인덱스가 즉시 업데이트되지 않는다고 주장 할 수있는 몇 가지 경우를 알고 있습니다. 이는 성능상의 이유로 수행되며 최종 사용자는 일관되지 않은 데이터를 볼 수 없습니다. 예를 들어, 삭제가 SQL Server의 인덱스에 완전히 적용되지 않는 경우가 있습니다. 백그라운드 프로세스가 실행되어 결국 데이터를 정리합니다. 궁금하다면 고스트 레코드 에 대해 읽을 수 있습니다 .