Скрытые функции в 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
Ответ 8
Предикат OVERLAPS недокументирован.
http://oraclesponge.wordpress.com/2008/06/12/the-overlaps-predicate/
Ответ 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, и вы увидите разность скоростей).
Ответ 15
Предложение WITH
Ответ 16
Таблицы моментальных снимков. Также найден в Oracle Lite и чрезвычайно полезен для развертывания собственного механизма репликации.
Ответ 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;
Ответ 19
Предложение модели (доступно для Oracle 10g и выше)
Ответ 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
не является детерминированной функцией, это может привести к неправильным результатам, поэтому будьте осторожны!