2010-08-11 3 views
3

열이 name varchar(20) 인 테이블이 있고 name = "abcdef"인 행을 저장한다고 가정합니다.어떻게 varchar2를 비효율적으로 만들지 않습니까?

INSERT INTO tab(id, name) values(12, 'abcdef'); 

방법 name에 대한 메모리 할당이 경우 수행 ?

은 내가 생각할 수있는 두 가지 방법이 있습니다 :

A)

20 바이트가 할당 만 6가 사용된다. 이 경우 varchar2은 메모리 할당과 관련하여 char보다 큰 이점이 없습니다.

b)

단지 6 바이트가 할당된다. 이 경우, 나는이 일 후에

INSERT INTO tab(id, name) values(13, 'yyyy'); 
INSERT INTO tab(id, name) values(14, 'zzzz'); 

을 더 행의 몇 가지를 CH3OH 후 나는 UPDATE를 할 경우,

UPDATE tab SET name = 'abcdefghijkl' WHERE id = 12; 

는 어디 DBMS는 필요한 추가 6 바이트를 얻을 않습니다 에서? 다음 6 바이트가 비어 있지 않은 경우가있을 수 있습니다 (처음에는 6 개만 할당되고 다른 바이트는 다음 바이트가 할당되었을 수 있습니다).

행을 새로운 장소로 이동하는 것 외에 다른 방법이 있습니까? 인덱스 구성 테이블의 경우에는 시프 팅 (shift)조차도 문제가 될 수 있습니다 (힙 (heap) 구성 테이블의 경우에는 괜찮을 수 있음).

+1

이것은 구현에 따라 다르지만 업데이트 할 때 새 행은 이전 행과 전혀 다른 위치에 작성됩니다. 이것은 varchar가 없어도 사실입니다. – hobbs

답변

1

는 일반적으로 사용하는 RDBMS에 따라 변화하지만,있을 수 있습니다. 크기는 허용되는 최대 값 일 뿐이며 할당되는 양은 아닙니다.

일부 시스템에서는 char 필드도 사용한다고 생각합니다. 가변 크기 데이터 유형은 효율적으로 처리되어 더 이상 최대 할당을 얻을 수 없습니다.

더 많은 공간이 필요하도록 레코드를 업데이트하면 동일한 할당 블록 내의 레코드가 아래로 이동하고 레코드가 더 이상 해당 블록에 맞지 않으면 다른 블록이 할당되고 레코드가 블록 사이에 분산됩니다 . 즉, 레코드가 할당 블록 내에서 연속되지만 블록이 디스크에서 연속적 일 필요는 없습니다.

+0

Oracle 및 DB2 시스템에서 NOT NULL CHAR (n BYTES) 필드는 항상 n 바이트를 사용합니다. –

1

확실히 더 많은 공간을 할당하지 않습니다. 이것은 가변 길이 유형을 사용하는 지점을 무력화시킵니다.

당신이 언급 한 경우 아래의 행이 페이지에서 아래로 이동해야한다고 생각할 수 있습니다. 어쩌면 이것이 어떻게 든 최적화되어있을 것입니다. 정확한 세부 사항을 모르겠다. 아마도 다른 사람이 더 이상 논평 할 수있을 것이다.

1

편집나는 이것이 태그 된 Microsoft SQL Server라고 생각했습니다. 나는 대답은 여전히 ​​관련이 생각하는 열 데이터 항목의 크기가 일치 할 때 official recommendation

  • 사용 문자는 이유

    하지만.

  • 열 데이터 항목의 크기가 상당히 다를 경우 varchar를 사용하십시오.
  • 열 데이터 항목의 크기가 상당히 달라질 때 varchar (max)를 사용하고 크기는 이 8,000 바이트를 초과 할 수 있습니다.

테이블 구조를 설계 할 때 고려해야 할 트레이드 오프입니다.아마도이 계산에서 읽는 업데이트의 빈도를 고려해야합니다.

주목할만한 점은 char의 경우 NULL 값이 여전히 모든 저장 공간을 사용한다는 것입니다. Management Studio에는 행이 어떻게 저장되는지 쉽게 볼 수있는 SQL Internals Viewer이라는 추가 기능이 있습니다. 당신이 varchar 필드에 저장

만 실제 데이터가 할당된다

1

이것은 데이터베이스 의존도가 매우 높습니다.

두 점 : MVCC 관찰 데이터베이스는 실제로 디스크 또는 메모리 캐시의 데이터를 업데이트하지 않습니다. 그들은 갱신 된 데이터로 새로운 행을 삽입하고 이전 행을 특정 트랜잭션에서 삭제 된 것으로 표시합니다. 잠시 후 삭제 된 행은 어떤 트랜잭션에서도 볼 수 없으며 회수됩니다. 저장 공간 문제를 해결하기위한

, 그것은 문자의 경우 1-4 bytes of header + data (+ padding)

의 형태로 통상의 데이터는 충분한 길이에 도달하도록 패딩된다. varchar 또는 text의 경우 헤더는 뒤 따르는 데이터의 길이를 저장합니다.

+0

MVCC 데이터베이스의 작동 방식이 Oracle의 작동 방식과 일치하지 않습니다. 오라클은 기존의 버전을 읽을 수 있도록 롤백 세그먼트 또는 실행 취소 테이블에서 변경 사항을 실행 취소하기위한 정보를 작성하면서 해당 위치에서 행을 업데이트합니다. 재실행 로그에 기록하는 것뿐만 아니라 실패시 변경 사항이 손실되지 않도록하십시오. –

1

질문 제목에 VARCHAR2가 주어지면 귀하의 질문이 Oracle에 초점을 맞추고 있다고 가정합니다. Oracle에서는 PCTFREE 절을 사용하여 데이터 블록 내에서 행 확장을위한 공간을 예약 할 수 있습니다. 이렇게하면 행을 길게 만드는 업데이트의 영향을 완화하는 데 도움이 될 수 있습니다.

그러나 Oracle에서 행을 다시 쓰려면 블록 내에 여유 공간이 없으면 행 마이그레이션이라고합니다. 디스크에 원래 주소를 남겨 둡니다 (인덱스를 반드시 업데이트 할 필요는 없습니다). 그러나 원래 위치에 데이터를 저장하는 대신 해당 행의 새 주소에 대한 포인터를 저장합니다.

많은 수의 행이 마이그레이션 된 경우 인덱스를 통해 테이블에 많이 액세스하는 경우 쿼리를 만족시키기 위해 추가 I/O가 추가되므로 성능 문제가 발생할 수 있습니다.

관련 문제