Oracle
 sql >> база данни >  >> RDS >> Oracle

Защо не трябва да направя всичките си VARCHAR2 само за PL/SQL 32767 байта?

Изглежда, че това е една от областите, в които функционалността на PL/SQL се е развила през версиите, когато Oracle е внедрил различни оптимизации.

Обърнете внимание, че това също означава, че някои от отговорите, изброени в OP, също са специфични за изданието, дори това да не е изрично споменато в тези въпроси/отговори. Когато времето изтече и използването на по-стари версии на Oracle приключи (мечтая ли?), тази информация ще стане остаряла (може да отнеме десетилетия на размисъл).

Заключението по-горе е подкрепено със следния цитат от глава 12 Настройване на PL/SQL приложения за производителност на PL/SQL Language Reference 11g R1 :

Този проблем вече не се споменава в 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 -attribute, тъй като това е начинът с нулево усилие да поддържате 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_size Заключавам, че декларираният размер на varchar2 няма значение. Тестът обаче може да е твърде наивен - коментарите са добре дошли!

Тестовият скрипт:

-- 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.

$


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL грешка:ORA-02298:не може да се потвърди (SYSTEM.AEROPUERTO_FK) - родителските ключове не са намерени

  2. Oracle - ВРЪЩАНЕ в комбинация с агрегатни функции

  3. Създаване или симулиране на двумерни масиви в PL/SQL

  4. Pandas към Oracle чрез SQL Alchemy:UnicodeEncodeError:кодекът 'ascii' не може да кодира символ

  5. Oracle sql - присъединяване с входен параметър