programing

PL/SQL 전용 VARCHAR232767 바이트를 모두 만들지 않는 이유는 무엇입니까?

elecom 2023. 10. 30. 20:32
반응형

PL/SQL 전용 VARCHAR232767 바이트를 모두 만들지 않는 이유는 무엇입니까?

아니면 그럴까요?

(이 제목은 Gary Myers가 Oracle varchar2에 정의 매개 변수로 필수 크기가 있는 이유에 대해 언급한 것에서 영감을 얻었습니다.)

다음 변수를 고려합니다.

declare
  -- database table column interfacing variable
  v_a tablex.a%type; -- tablex.a is varchar2
  -- PL/SQL only variable
  v_b varchar2(32767); -- is this a poor convention ?
begin
  select a into v_a from tablex where id = 1;
  v_b := 'Some arbitrary string: ' || v_a; -- ignore potential ORA-06502
  insert into tabley(id, a) values(1, v_a); -- tablex.a and tabley.a types match
  v_b := v_b || ' More arbitrary characters';
end;
/

v_a데이터베이스 테이블 열을 인터페이스하는 데 사용되므로 속성을 사용합니다.하지만 데이터 유형이varchar2왜 사용하지 말아야 합니까?varchar2(4000)아니면varchar2(32767)또한 데이터베이스 열에서 읽은 문자열이 PL/SQL 변수에 항상 맞는다는 것을 보장합니까?이 관습에 반대하는 다른 주장이 있습니까?%type성 ?

v_b 등/SQL으로 JDBC트(Java/Python 프로그램, Oracle SOA/OSB등).UTL_FILE일 경우. 만약.varchar2예를 들어 csv-line을 사용하여 가능한 정확한 최대 길이를 계산해야 하는 이유를 제시합니다(라인이 모든 경우에 32767 바이트에 맞는지 확인하는 것을 제외하고).clob) 및 데이터 모델이 변경될 때마다 다시 calculate할 수 있습니까?

여기에는 많은 질문들이 포함되어 있습니다.varchar2SQL에서 의미론을 길게 지정하고 그 이유를 설명합니다.varchar2(4000)SQL의 잘못된 practice입니다. SQL과 한 SQL과 PL/SQL의 varchar2은 잘 type 됨:

APC의 답변에서 제가 이 문제에 대해 논의한 유일한 지점은 3번과 4번입니다.

데이터베이스는 PL/SQL 컬렉션에 대해 메모리를 할당할 때 변수의 길이를 사용합니다.그 메모리가 PGA 슈퍼사이즈에서 나오기 때문에 서버의 메모리 부족으로 인해 프로그램이 실패할 수 있습니다.

PL/SQL 프로그램에서 단일 변수 선언과 유사한 문제가 있지만, 컬렉션은 문제를 곱하는 경향이 있습니다.

, Feuerstein 의 PL/SQL Programming, 5판 .varchar2변수가 중요한 실수는 아니지 않습니까?

갱신하다

구글링을 좀 더 해본 결과, Oracle 문서가 릴리스되는 동안 발전했다는 사실을 알게 되었습니다.

PL/SQL 사용자 설명서 및 참조 10g 릴리스 2 3장 PL/SQL 데이터 유형의 인용:

작은 VARCHAR2 변수는 성능에 최적화되어 있고, 큰 변수는 효율적인 메모리 사용에 최적화되어 있습니다.컷오프 포인트는 2000바이트입니다.2000바이트 이상의 VARCHAR2의 경우 PL/SQL은 실제 값을 유지할 수 있는 메모리만 동적으로 할당합니다.2000바이트보다 짧은 VARCHAR2 변수의 경우 PL/SQL은 해당 변수의 전체 선언 길이를 미리 할당합니다.예를 들어 VARCHAR2(2000 바이트) 변수와 VARCHAR2(1999 바이트) 변수에 동일한 500바이트 값을 할당하면 전자가 500바이트를 차지하고 후자가 1999바이트를 차지합니다.

PL/SQL 사용자 설명서 및 참조 11g 릴리스 1 3장 PL/SQL 데이터 유형의 인용:

CHAR 변수의 경우 또는 최대 크기가 2,000바이트 미만인 VARCHAR2 변수의 경우 PL/SQL은 컴파일 시 최대 크기에 충분한 메모리를 할당합니다.최대 크기가 2,000바이트 이상인 VARCHAR2의 경우, PL/SQL은 런타임에 실제 값을 저장할 수 있는 충분한 메모리를 할당합니다.이러한 방식으로 PL/SQL은 성능을 위해 더 작은 VARCHAR2 변수를 최적화하고 효율적인 메모리 사용을 위해 더 큰 변수를 최적화합니다.

예를 들어 VARCHAR2(1999 BYTE) 및 VARCHAR2(2000 BYTE) 변수에 동일한 500바이트 값을 할당하는 경우 PL/SQL은 컴파일 시 이전 변수에 1999바이트를 할당하고 실행 시에는 후자 변수에 500바이트를 할당합니다.

그러나 PL/SQL 사용 설명서 및 Reference 11g Release 2 3장 PL/SQL Datatype은 메모리 할당에 대해 더 이상 언급하지 않으며 메모리 할당에 대한 다른 정보를 전혀 찾을 수 없습니다. (이 Release를 사용하고 있기 때문에 11.2 설명서만 확인합니다.PL/SQL 사용자 설명서 및 참조 12c 릴리스 1 챕터 3 PL/SQL 데이터 유형에 대해서도 마찬가지입니다.

저는 또한 제프리 켐프가 이 질문을 다루는 답변을 찾았습니다.그러나 Jeffrey의 답변은 10.2 문서를 언급하고 있으며 PL/SQL에 대한 질문은 전혀 아닙니다.

Oracle이 다양한 최적화를 구현했을 때 PL/SQL 기능이 릴리스에 비해 진화한 분야 중 하나인 것으로 보입니다.

또한 OP에 나열된 답변 중 일부는 해당 질문/답변에 명시적으로 언급되지 않은 릴리스별 답변임을 의미합니다.시간이 흘러 오래된 Oracle 릴리스의 사용이 종료되면(꿈꾸는 일?) 정보가 구식이 됩니다(생각하는 데 수십 년이 걸릴 수 있습니다).

위의 결론은 제12장 PL/SQL Applications for Performance of PL/SQL Language Reference 11g R1에서 인용한 다음과 같습니다.

VARCHAR2 4000자 이상 변수 선언

식 결과의 크기를 확실히 알 수 없는 경우에는 큰 VARCHAR2 변수를 할당해야 할 수 있습니다.256 또는 1000을 지정하는 등 높은 쪽으로만 추정하는 대신 32000과 같이 크기가 큰 VARCHAR2 변수를 선언하여 메모리를 절약할 수 있습니다.PL/SQL은 오버플로 문제를 방지하면서도 메모리를 절약할 수 있도록 최적화 기능을 갖추고 있습니다.VARCHAR2 변수의 크기를 4000자 이상으로 지정합니다. PL/SQL은 변수를 할당할 때까지 기다린 다음 필요한 만큼의 스토리지만 할당합니다.

이 문제는 문서의 11g R2 또는 12c R1 버전에서는 더 이상 언급되지 않습니다.이는 제3장 PL/SQL 데이터 유형의 발전과 일맥상통합니다.

답변:

11gR2이기 때문에 메모리 사용 시점과 차이가 없습니다.varchar2(10)아니면varchar2(32767) Oracle PL/SQL 컴파일러는 최적의 방법으로 더러운 세부사항을 처리할 것입니다!

11gR2 이전 릴리스의 경우 다양한 메모리 관리 전략이 사용되는 차단 지점이 있으며 이는 각 릴리스의 PL/SQL Language Reference에 명확하게 나와 있습니다.

위 내용은 문제 도메인에서 도출할 수 있는 자연 길이 제한이 없는 경우에만 PL/SQL 전용 변수에 적용됩니다.varchar2 변수가 GTIN-14를 나타내는 경우 다음과 같이 선언해야 합니다.varchar2(14).

테이블 열이 있는 PL/SQL 변수 인터페이스가 사용되는 경우%type-그것이 PL/SQL 코드와 데이터베이스 구조를 동기화하기 위한 제로 노력 방식이기 때문입니다.

메모리 테스트 결과:

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0에서 메모리 분석을 실행하면 다음과 같은 결과가 나타납니다.

str_size iterations UGA   PGA
-------- ---------- ----- ------
10       100        65488 0
10       1000       65488 65536
10       10000      65488 655360
32767    100        65488 0
32767    1000       65488 65536
32767    10000      65488 655360

왜냐하면 PGA의 변화는 동일하고 오직 의존하기 때문입니다.iterations아닌str_sizevarchar2 신고된 크기는 중요하지 않다고 결론지었습니다.하지만 이 테스트는 너무 순진한 것일 수도 있습니다. 댓글을 환영합니다!

테스트 스크립트:

-- plsql_memory is a convenience package wrapping sys.v_$mystat s and
-- sys.v_$statname tables written by Steven Feuerstein and available in the
-- code-zip file accompanying his book.

set verify off

define str_size=&1
define iterations=&2

declare
  type str_list_t is table of varchar2(&str_size);
begin
  plsql_memory.start_analysis;

  declare
    v_strs str_list_t := str_list_t();
  begin
    for i in 1 .. &iterations
    loop
      v_strs.extend;
      v_strs(i) := rpad(to_char(i), 10, to_char(i));
    end loop;
    plsql_memory.show_memory_usage;
  end;

end;
/

exit

테스트 실행 예제:

$ sqlplus -SL <CONNECT_STR> @memory-test.sql 32767 10000

Change in UGA memory: 65488 (Current = 1927304)
Change in PGA memory: 655360 (Current = 3572704)

PL/SQL procedure successfully completed.

$

아마도 제가 나이를 먹어서인지, 그 어떤 시스템도 가장 많은 메모리가 48,000이었고, 행복한 날들이 64,000까지 있었던 시대에 제가 나이를 먹었기 때문일 것입니다.가상이 아니라 할당한 것이 (wyaiwyg)(WAY-WIG?)입니다.저는 많은 젊은 프로그래머들이 자신의 디자인에 게으르고 더 많은 기억을 던져서 디자인의 결함을 숨기는 경향을 봅니다.

우리가 그냥 타이핑하는 습관이 생긴다면,varchar2(MAX)문자열 변수를 정의할 때마다 길이에 대한 생각을 중단합니다.하지만 때로는 길이가 중요합니다.아직 그렇게 하지 않았다면 입력하자마자(그러면 우리는 멈춰서 얼마나 큰 것이 필요한지 생각해 봐야 합니다.여기서 사이즈가 문제가 됩니까?그렇다면 합리적인 최대값(또는 최소값)은 얼마입니까?이를 통해 바이트, 필드 및 인덱스를 넘어 실제 작업을 시도하는 "사물"을 살펴볼 수 있습니다.그것은 결코 나쁜 생각이 아닙니다.

훈육이 어렵습니다.우리는 할 수 있을 때마다 그것을 시행하는 습관을 길러야 합니다.좋은 데이터와 코드 설계는 본질적으로 어렵습니다.조금 더 쉽게 만들기 위해 사용할 수 있는 도구와 기술이 있지만, 더 쉽다고 해서 아무것도 해서는 안 됩니다.그것이 다크 사이드로 가는 길이고 조만간 우리를 따라잡을 겁니다.

문제는 다른 소프트웨어와 동일하다고 생각합니다. 메모리를 너무 많이 할당하면 성능이 저하되고 메모리가 모든 메모리를 차지했다는 사실로 인해 실패할 가능성이 낮아진다는 것입니다.

내 생각에는, 사용.%type데이터 유형이나 길이를 변경할 때 실수를 방지하고 해당 변수의 원점을 명확하게 하기 때문에 가능한 한 많이 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/24831972/why-shouldnt-i-make-all-my-pl-sql-only-varchar2-32767-bytes

반응형