Скрытые функции в Oracle

Мне понравились ответы и вопросы о скрытых функциях в sql-сервере

Что вы можете сказать нам об Oracle?
Скрытые таблицы, внутренние работы..., секретные хранимые процедуры, пакет, который имеет хорошие утилиты...

Ответ 1

Поскольку Apex теперь является частью каждой базы данных Oracle, эти служебные функции Apex полезны, даже если вы не используете Apex:

SQL> declare
  2    v_array apex_application_global.vc_arr2;
  3    v_string varchar2(2000);
  4  begin
  5  
  6    -- Convert delimited string to array
  7    v_array := apex_util.string_to_table('alpha,beta,gamma,delta', ',');
  8    for i in 1..v_array.count
  9    loop
 10      dbms_output.put_line(v_array(i));
 11    end loop;
 12  
 13    -- Convert array to delimited string
 14    v_string := apex_util.table_to_string(v_array,'|');
 15    dbms_output.put_line(v_string);
 16  end;
 17  /
alpha
beta
gamma
delta
alpha|beta|gamma|delta

PL/SQL procedure successfully completed.

Ответ 2

"Полное сканирование таблицы не всегда плохое. Индексы не всегда хороши".

Метод доступа на основе индексов менее эффективен при чтении строк, чем полное сканирование, когда вы измеряете его в терминах строк, доступных на единицу работы (обычно для каждого логического чтения). Однако многие инструменты интерпретируют полное сканирование таблицы как признак неэффективности.

Возьмем пример, когда вы читаете несколько сотен счетов-фактур в таблице счетов и просматриваете способ оплаты в небольшой таблице поиска. Использование индекса для проверки таблицы поиска для каждого счета-фактуры, вероятно, означает три или четыре логических io для счета-фактуры. Однако полное сканирование таблицы поиска при подготовке к хеш-соединению из данных счета-фактуры, вероятно, потребует всего лишь нескольких логических чтений, а сам хеш-соединение будет вообще отсутствовать в памяти почти без затрат.

Однако многие инструменты будут смотреть на это и увидеть "полное сканирование таблицы" и попросить использовать индекс. Если вы это сделаете, вы можете просто отменить свой код.

Кстати, зависимость от индексов, как в приведенном выше примере, приводит к тому, что "Коэффициент попадания кэша буфера" возрастает. Вот почему BCHR - это, в основном, нонсенс как предиктор эффективности системы.

Ответ 3

Указание мощности в основном недокументировано.

 explain plan for
 select /*+ cardinality(@inner 5000) */ *
 from   (select /*+ qb_name(inner) */ * from dual)
 /
 select * from table(dbms_xplan.display)
 /
 --------------------------------------------------------------------------
 | Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
 --------------------------------------------------------------------------
 |   0 | SELECT STATEMENT  |      |  5000 | 10000 |     2   (0)| 00:00:01 |
 |   1 |  TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
 --------------------------------------------------------------------------

Ответ 4

Коэффициент попадания кэша буфера практически бессмыслен как предиктор эффективности системы

Ответ 5

Вы можете просмотреть данные таблицы по состоянию на предыдущее время с помощью Flashback Query с определенными ограничениями.

Select *
  from my_table as of timestamp(timestamp '2008-12-01 15:21:13')

11g имеет совершенно новый набор функций, сохраняющий более важные исторические изменения.

Ответ 6

Частая перестройка индексов почти всегда пустая трата времени.

Ответ 7

wm_concat работает как MySql group_concat, но он недокументирован.

с данными:

-car-   -maker-
Corvette Chevy
Taurus   Ford
Impala   Chevy
Aveo     Chevy

select wm_concat(car) Cars, maker from cars
group by maker

дает вам:

-Cars-                   -maker-
Corvette, Impala, Aveo   Chevy
Taurus                   Ford

Ответ 9

Я только что узнал о псевдоколоне Ora_rowSCN. Если вы не настроите таблицу для этого, этот pcolumn дает вам блок SCN. Это может быть действительно полезно для чрезвычайной ситуации: "О, дерьмо, у меня нет аудита на этой таблице, и задаюсь вопросом, изменил ли кто-то данные со вчерашнего дня".

Но даже лучше, если вы создадите таблицу с Rowdependecies ON. Это помещает SCN последнего изменения в каждую строку. Это поможет вам избежать проблемы с "Потерянным правлением" без необходимости включать каждый столбец в свой запрос.

IOW, когда приложение захватывает строку для изменения пользователя, также выберите Ora_rowscn. Затем, когда вы публикуете редактирование пользователя, добавьте Ora_rowscn = v_rscn в дополнение к уникальному ключу в предложении where. Если кто-то коснулся строки после того, как вы ее схватили, ака потеряла правку, обновление будет соответствовать нулевым строкам с тех пор, как изменится ora_rowscn.

Так здорово.

Ответ 10

Если вы получите значение столбца PASSWORD на DBA_USERS, вы можете создавать резервные копии/восстанавливать пароли, не зная их:

 ALTER USER xxx IDENTIFIED BY VALUES 'xxxx';

Ответ 11

Обходить буферный кеш и читать прямо с диска с помощью чтения прямого пути.

alter session set "_serial_direct_read"=true;

Вызывает контрольную точку табличного пространства (9i) или быстрого объекта (10g +), так что будьте осторожны в занятых OLTP-системах.

Ответ 12

Больше недокументированных материалов на http://awads.net/wp/tag/undocumented/

Предупреждение: используйте на свой страх и риск.

Ответ 13

Я не знаю, считается ли это скрытым, но я был очень доволен, когда увидел этот способ быстро увидеть, что произошло с инструкцией SQL, которую вы настраиваете.

SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM DUAL;

SELECT * FROM TABLE(dbms_xplan.display_cursor( NULL, NULL, 'RUNSTATS_LAST'))
;

PLAN_TABLE_OUTPUT
-----------------------------------------------------
SQL_ID  5z36y0tq909a8, child number 0
-------------------------------------
SELECT /*+ GATHER_PLAN_STATISTICS */ * FROM DUAL

Plan hash value: 272002086

---------------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
---------------------------------------------------------------------------------------------
|   1 |  TABLE ACCESS FULL| DUAL |      1 |      1 |      1 |00:00:00.02 |       3 |      2 |
---------------------------------------------------------------------------------------------


12 rows selected.

Где:

  • E-Rows - это оцененные строки.
  • A-Строки - это фактические строки.
  • A-Время - это фактическое время.
  • Буферы - это фактические буферы.

Если оценочный план отличается от фактического исполнения на порядок, вы знаете, что у вас есть проблемы.

Ответ 14

Не скрытая функция, но функция Finegrained-access-control (FGAC), также известная как безопасность на уровне строк, является тем, что я использовал в прошлом, и был впечатлен эффективностью ее реализации. Если вы ищете что-то, что гарантирует, что вы можете контролировать детализацию того, как строки подвергаются пользователям с разными разрешениями - независимо от приложения, которое используется для просмотра данных (SQL * Plus, а также вашего веб-приложения) - тогда это драгоценный камень.

Встроенная полнотекстовая индексация более широко документирована, но по-прежнему выделяется из-за ее стабильности (просто попробуйте запустить полное переиндексацию столбцов с полнотекстовой индексацией на аналогичных образцах данных в MS-SQL и Oracle, и вы увидите разность скоростей).

Ответ 17

@Peter

Фактически вы можете привязать переменную типа "Курсор" в TOAD, а затем использовать ее в своем заявлении и отобразить результаты в сетке результатов.

exec open :cur for select * from dual;

Ответ 18

Q: Как вызвать сохраненный курсором из TOAD?

A: Пример, измените на свой курсор, имя_пакета и сохраненное имя proc

declare cursor PCK_UTILS.typ_cursor;  

begin   
    PCK_UTILS.spc_get_encodedstring(  
        'U',  
        10000002,  
        null,  
        'none',  
        cursor);  
end;

Ответ 20

WM_CONCAT для агрегации строк

Ответ 21

Скалярное кэширование подзапросов является одной из самых удивительных функций в Oracle

-- my_function is NOT deterministic but it is cached!
select t.x, t.y, (select my_function(t.x) from dual)
from t

-- logically equivalent to this, uncached
select t.x, t.y, my_function(t.x) from t

Подзапрос "кэширования" выше оценивает my_function(t.x) только один раз за уникальное значение t.x. Если у вас большие разделы одного и того же значения t.x, это значительно ускорит ваши запросы, даже если my_function не объявлен DETERMINISTIC. Даже если это было DETERMINISTIC, вы можете защитить себя, возможно, дорогим SQL → PL/SQL контекстным переключателем.

Конечно, если my_function не является детерминированной функцией, это может привести к неправильным результатам, поэтому будьте осторожны!