:: Не фоксом единым
Re: Oracle. Администрирование.
sphinx

Сообщений: 31189
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
ВладимирС
NEXT_DAY ФУНКЦИЯ
Узнайте, как использовать Oracle / PLSQL функцию NEXT_DAY с синтаксисом и примерами.
Описание

Функция Oracle / PLSQL NEXT_DAY возвращает первый день недели, который больше date.
Синтаксис

Синтаксис функции Oracle / PLSQL NEXT_DAY:
NEXT_DAY( date, weekday )
Параметры или аргументы

date используется для поиска следующего дня недели
weekday это день недели (это: понедельник, вторник, среда, четверг, пятница, суббота, воскресенье)



Наверное, надо в настройках посмотреть, как часто собирается статистика (например, раз в неделю), а потом от поля last_analyzed применить NEXT_DAY(). А если раз в месяц - через ADD_MONTHS().

oracleplsql.ru


------------------
"Veni, vidi, vici!"(с)




Исправлено 1 раз(а). Последнее : sphinx, 24.08.16 10:27
Ratings: 1 negative/0 positive
Re: Oracle. Администрирование.
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
docs.oracle.com
Цитата:
The recommended approach to gathering optimizer statistics is to allow Oracle Database to automatically gather the statistics. Oracle Database gathers optimizer statistics on all database objects automatically and maintains those statistics as an automated maintenance task. The automated maintenance tasks infrastructure (known as AutoTask) schedules tasks to run automatically in Oracle Scheduler windows known as maintenance windows. By default, one window is scheduled for each day of the week. You can customize attributes of these maintenance windows, including start and end time, frequency, and days of the week. AutoTask schedules statistics gathering as an automated maintenance task in the maintenance windows to automatically collect optimizer statistics for all schema objects in the database for which there are no statistics or only stale statistics. This process is called automatic optimizer statistics collection.
По умолчанию в будние дни окно открывается в 22:00 на 4 часа (до 02:00 следующего дня), в выходные с 06:00 на 20 часов (тоже до 02:00 следующего дня).


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
ВладимирС
Автор

Сообщений: 1693
Дата регистрации: 03.11.2005
Igor Korolyov
docs.oracle.com
Цитата:
The recommended approach to gathering optimizer statistics is to allow Oracle Database to automatically gather the statistics. Oracle Database gathers optimizer statistics on all database objects automatically and maintains those statistics as an automated maintenance task. The automated maintenance tasks infrastructure (known as AutoTask) schedules tasks to run automatically in Oracle Scheduler windows known as maintenance windows. By default, one window is scheduled for each day of the week. You can customize attributes of these maintenance windows, including start and end time, frequency, and days of the week. AutoTask schedules statistics gathering as an automated maintenance task in the maintenance windows to automatically collect optimizer statistics for all schema objects in the database for which there are no statistics or only stale statistics. This process is called automatic optimizer statistics collection.
По умолчанию в будние дни окно открывается в 22:00 на 4 часа (до 02:00 следующего дня), в выходные с 06:00 на 20 часов (тоже до 02:00 следующего дня).
Большое спасибо тебе...
Про 22:00 я тоже слышал... Но где это прописано ? Может JOB запускается в 22:00... но не могу найти...
Почему спрашиваю... Из результатов запроса:
SELECT last_analyzed, table_name, num_rows, sample_size
FROM dba_tables
WHERE owner = 'ZAGS_DATA1'
ORDER by last_analyzed;
last_analyzed       table_name                  num_rows    sample_size
..................................................................
22.08.2016 22:31:39 LNK_REGISTER_FLAGS_PRINTED  199871      199871
22.08.2016 22:33:27 T_ORG_DECLENSIONS           578245      578245
23.08.2016 11:48:59 REGISTER                    452832      452832
23.08.2016 11:51:56 T_PEOPLE                    1987435     1987435
23.08.2016 11:53:54 T_PEOPLE_INFO               1987400     1987400
23.08.2016 11:54:16 T_PEOPLE_DOC                653632      653632
23.08.2016 11:55:53 REGISTER_BIRTH              210729      210729
23.08.2016 11:55:58 REGISTER_BIRTH_ADDITION     210709      210709
23.08.2016 11:56:00 REGISTER_BIRTH_FLAGS        210713      210713
23.08.2016 11:56:04 REGISTER_DEAD               169835      169835
23.08.2016 11:56:06 REGISTER_DEAD_ADDITION      19438       19438
23.08.2016 11:56:08 REGISTER_DEAD_FLAGS         98280       98280
Вижу что многие в 22:00 начинают, но почему есть таблицы, которые в 11:00 начинают... Непонятно... как это проанализировать ?



Исправлено 2 раз(а). Последнее : ВладимирС, 24.08.16 13:01
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Наверное кто-то вручную запустил сбор статистики...
Информация об автоматических заданиях, в т.ч. лог исполнения (конечно же если он не выключен) видна в системных представлениях:
SELECT *
FROM DBA_SCHEDULER_JOB_LOG
WHERE JOB_CLASS LIKE 'ORA$AT_JC%_OS'
ORDER BY LOG_DATE DESC;
SELECT *
FROM DBA_SCHEDULER_JOB_RUN_DETAILS
WHERE JOB_NAME LIKE 'ORA$AT_OS_%'
ORDER BY LOG_DATE DESC;
SELECT *
FROM DBA_AUTOTASK_CLIENT
WHERE CLIENT_NAME = 'auto optimizer stats collection';
SELECT *
FROM DBA_AUTOTASK_JOB_HISTORY
WHERE CLIENT_NAME = 'auto optimizer stats collection'
ORDER BY JOB_START_TIME DESC;
SELECT * FROM DBA_AUTOTASK_WINDOW_CLIENTS;
SELECT *
FROM DBA_AUTOTASK_CLIENT_HISTORY
WHERE CLIENT_NAME = 'auto optimizer stats collection'
ORDER BY WINDOW_START_TIME DESC;


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
ВладимирС
Автор

Сообщений: 1693
Дата регистрации: 03.11.2005
Igor Korolyov
Наверное кто-то вручную запустил сбор статистики...
Информация об автоматических заданиях, в т.ч. лог исполнения (конечно же если он не выключен) видна в системных представлениях:
....
SELECT *
FROM DBA_AUTOTASK_JOB_HISTORY
WHERE CLIENT_NAME = 'auto optimizer stats collection'
ORDER BY JOB_START_TIME DESC;
....
Блин... как приятно, что такие люди есть...:beer2:
Запрос:
SELECT *
FROM DBA_AUTOTASK_CLIENT_HISTORY
WHERE CLIENT_NAME = 'auto optimizer stats collection'
ORDER BY WINDOW_START_TIME DESC;
Сразу и выдал:
       CLIENT_NAME             :  WINDOW_NAME :         WINDOW_START_TIME       : WINDOW_DURATION   :JOBS_CREATED:JOBS_STARTED:JOBS_COMPLETED:       WINDOW_END_TIME           :
auto optimizer stats collection TUESDAY_WINDOW 23/08/2016 22:00:00,292000 +03:00 +00 16:10:52.993000       1           1              1       24/08/2016 14:10:53,285000 +03:00
auto optimizer stats collection MONDAY_WINDOW  22/08/2016 22:00:00,652000 +03:00 +00 03:59:59.681000       1           1              1       23/08/2016 2:00:00,333000 +03:00
Но что ему помешало закончить работу в 02:00 ? Для меня пока загадка...
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Там есть какой-то косяк - он неверно показывает для последнего окна дату завершения... Патча сервер просит На самом деле можно увидеть в других представлениях что окно закрыто да и сама программа сбора не работает.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
ВладимирС
Автор

Сообщений: 1693
Дата регистрации: 03.11.2005
Моя задача (может ее решать как-то по другому), но пока не придумал... прошу совета...
Есть пользователь ZAGS_DATA1
У него
GRANT DBA TO ZAGS_DATA1 WITH ADMIN OPTION;

Под ним легко выполняется :
Т.е.
1. обращение к системным вьюхам: dba_indexes, all_constraints
2. права использования:
ALTER INDEX [имя] UNUSABLE
ALTER INDEX [имя] REBUILD

Но мне надо, чтобы другой пользователь выполнял тоже самое, но права GRANT DBA недавать...
Как сделать это ?
Я решил создать вьюху у пользователя ZAGS_DATA1
И потом другому пользователю дать чтение на эту вьюху...
Конечно еще проблема с правами на ALTER INDEX
Но даже и при создании вьюхи для пользователя ZAGS_DATA1:
Выдается сообщение: ORA-01031: привилегий недостаточно
Как поступать ?
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
pasha_usue

Сообщений: 3650
Откуда: Е-бург
Дата регистрации: 06.10.2006
А функцию, выполняющуюся с правами создателя нельзя сделать?
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
ВладимирС
Автор

Сообщений: 1693
Дата регистрации: 03.11.2005
Все... разобрался...

Использовал таблицу не dba_indexes, а all_indexes...

Ну и начальник сказал дать гранты на изменение INDEX... (прописать ее в роль), а пользователю права на эту роль...
GRANT ALTER ANY INDEX TO APPLICATION_ROLE;
(Хотя мое мнение так делать нельзя (пользователю разрешено редактировать любой индекс)... Но он начальник...)

Все заработало...



Исправлено 2 раз(а). Последнее : ВладимирС, 26.08.16 11:47
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
1 - пользователь с правами DBA не должен использоваться никем кроме DBA - ни программами, ни просто людьми отличными от DBA - иначе базе придёт карачун и очень быстро
2 - несколько странная постановка задачи:
- зачем вообще отключать индексы? Что за процесс таким образом "оптимизируется", и почему вообще возникает такое желание - перестраивать индексы "потом" а не просто поддерживать их в процессе работы?
- зачем трогать "чужие" индексы? Ну ладно ещё свои собственные - для чего хватит доступа к user_indexes и не нужны никакие особые права, но для чужих... Это требует привилегии ALTER ANY INDEX - при том если речь про код исполняющийся из ХП, то привилегию надо дать напрямую пользователю, не через роль - ну или заморачиваться с "включением" ролей в данной ХП.

3 - доступ к системным представлениям dba_* даёт роль SELECT_CATALOG_ROLE - но она не даёт "наследуемый" доступ, т.е. даже если в схеме имеющей доступ (через эту роль, или через роль DBA включающую практически ВСЁ) к dba_* попытаться сделать своё представление на основе dba_* то ничего не выйдет - нужно явное и прямое разрешение на SELECT из соответствующего dba_* представления. А чтобы такое представление смогли использовать другие схемы, нужно ещё и про WITH GRANT OPTION не забыть - иначе "передоверить" доступ не получится.
Короче НЕ НАДО пользоваться этими dba_* простым пользователям - им должно быть достаточно представлений группы user_* и all_*

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

P.S. ХП и так выполняются по умолчанию "с правами создателя" - другое дело, что права полученные не напрямую а через роль не активны для такой ХП. Т.е. чисто теоретически сделать во всех нужных схемах ХП отключающие/перестраивающие "свои" индексы можно - но я ещё раз скажу что для выполнения таких издевательств над БД нужно иметь ОЧЕНЬ серьёзные основания. И ОЧЕНЬ хорошо понимать все последствия работы (даже временной) "без индексов".


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
ВладимирС
Автор

Сообщений: 1693
Дата регистрации: 03.11.2005
Igor Korolyov
1 - пользователь с правами DBA не должен использоваться никем кроме DBA - ни программами, ни просто людьми отличными от DBA - иначе базе придёт карачун и очень быстро
Уже так сделано, не мной... У нас есть 1 пользователь права его DBA...
Igor Korolyov
2 - несколько странная постановка задачи:
- зачем вообще отключать индексы?
Да, тут начали грузить кучу туеву данных, индексы видимо тормозят.
Попросили написать скрипт отключения индексов... Т.к. данные грузятся в разные схемы, то и отключать/обновлять индексы приходится в разных схемах...
Затем они данные загрузят...
Затем скрипт обновления индексов...
Igor Korolyov
- зачем трогать "чужие" индексы?
Дык завели пользователя, который запускает WEB-приложение... Ну и начинается раздача ему прав... Так можно дойти, что он в конечном итоге будет чуть ли не DBA...
Igor Korolyov
3 - доступ к системным представлениям dba_* даёт роль SELECT_CATALOG_ROLE - но она не даёт "наследуемый" доступ, т.е.
даже если в схеме имеющей доступ (через эту роль, или через роль DBA включающую практически ВСЁ) к dba_* попытаться сделать своё представление на основе dba_*
то ничего не выйдет - нужно явное и прямое разрешение на SELECT из соответствующего dba_* представления.
А чтобы такое представление смогли использовать другие схемы, нужно ещё и про WITH GRANT OPTION не забыть - иначе "передоверить" доступ не получится.
Короче НЕ НАДО пользоваться этими dba_* простым пользователям - им должно быть достаточно представлений группы user_* и all_*
Спа... я догадался, что использовать надо было all_*.
Igor Korolyov
В общем я бы сильно подумал именно про "может ее решать как-то по другому" - а не заморачивался с подобным
откровенно плохим (по реализуемой идее, не по синтаксису ) кодом...
Дык похоже надо идеологих проекта так менять...
Мне вообще непонравилось, что создали пользователя и теперь ему расширяют права...(не мной, а вышестоящими).

Igor Korolyov
P.S. ХП и так выполняются по умолчанию "с правами создателя" - другое дело, что права полученные не напрямую
а через роль не активны для такой ХП. Т.е. чисто теоретически сделать во всех нужных схемах ХП отключающие/перестраивающие "свои" индексы можно -
но я ещё раз скажу что для выполнения таких издевательств над БД нужно иметь ОЧЕНЬ серьёзные основания.
И ОЧЕНЬ хорошо понимать все последствия работы (даже временной) "без индексов".
Да, есть над чем размышлять... Но пока так...


Исправлено 1 раз(а). Последнее : ВладимирС, 26.08.16 12:47
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Ну это да, если нету авторитетного DBA или он не выполняет своих функций, то так и бывает - у всех полный доступ, всё ломается/засирается, проблемы только нарастают... У нас даже у разработчиков на девелоперских базах нет ни DBA, ни даже банальных SELECT ANY TABLE прав
Поди про recovery с backup-ами оне даже и не слыхивали


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
ВладимирС
Автор

Сообщений: 1693
Дата регистрации: 03.11.2005
Дали оптимизировать запрос (очень много жрет CPU, а если много раз вызывается, что на самом деле и происходит, то приложение висит):
SELECT O.ID,
OU.ID_TYPE_ORG,
O.SHORT_NAME,
O.FULL_NAME,
O.FIRM_NAME,
O.ID_UNIQ,
NVL (O.DATE_BEGIN, TO_DATE ('01.01.1999', 'DD.MM.YYYY')) AS DATE_BEGIN,
NVL (O.DATE_END, TO_DATE ('01.01.2999', 'DD.MM.YYYY')) AS DATE_END,
OU.ID_PARENT,
OU.FLAG_INDIVIDUAL,
O.FLAG_ACTUAL,
OU.POST_INDEX,
OU.BOSS,
OU.TEL_BOSS,
OU.KPP,
OU.OGRN,
OU.INN,
OU.OKPO,
OU.ID_LOCATION,
O.ID_USER,
O.DATE_REC,
OU.CODE_STATUS,
OU.NAME_STATUS,
r.id_output_role ID_ROLE_ORGANIZATION
FROM ZAGS_NSI.SP_ORGANIZATION O
INNER JOIN ZAGS_NSI.SP_ORGANIZATION_UNIQ OU ON OU.id = O.ID_UNIQ
INNER JOIN
(SELECT O.ID, roles.id_output_role
FROM
(SELECT O.ID, p2.ID_ROLE_ORGANIZATION
FROM ZAGS_NSI.SP_ORGANIZATION O
INNER JOIN
(SELECT t.ID_ROLE_ORGANIZATION, O.ID_UNIQ
FROM ZAGS_NSI.SP_ORGANIZATION O
LEFT JOIN LNK_ORGANIZATION_GUID l ON O.ID = l.ID_SP_ORGANIZATION
LEFT JOIN T_ORGANIZATION t ON t.ID = l.ID_T_ORGANIZATION
WHERE t.ID_ROLE_ORGANIZATION IS NOT NULL
UNION
SELECT ID_ROLES_ORGANIZATION,ID_SP_ORGANIZATION
FROM LNK_ROLES_ORGANIZATION
) p2
ON O.ID_UNIQ = p2.ID_UNIQ
GROUP BY O.ID, p2.ID_ROLE_ORGANIZATION
) O
INNER JOIN
(SELECT r.id, r.id AS id_output_role
FROM sp_roles_organization r
UNION ALL
SELECT r.id, r.id_parent AS id_output_role
FROM sp_roles_organization r
WHERE r.id_parent IS NOT NULL
) roles
ON O.ID_ROLE_ORGANIZATION = roles.id
GROUP BY O.ID, roles.id_output_role
) r
ON r.ID = O.id;

Посмотрел план:
Plan hash value: 2778163355
 
-------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name                        | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                             | 19812 |  5862K|       |  7915   (1)| 00:01:35 |
|*  1 |  HASH JOIN                        |                             | 19812 |  5862K|       |  7915   (1)| 00:01:35 |
|   2 |   VIEW                            |                             | 19812 |   503K|       |  7734   (1)| 00:01:33 |
|   3 |    HASH GROUP BY                  |                             | 19812 |   677K|       |  7734   (1)| 00:01:33 |
|*  4 |     HASH JOIN                     |                             | 19812 |   677K|       |  7732   (1)| 00:01:33 |
|   5 |      VIEW                         |                             |    55 |   935 |       |     4   (0)| 00:00:01 |
|   6 |       UNION-ALL                   |                             |       |       |       |            |          |
|   7 |        INDEX FULL SCAN            | SP_ROLES_ORGANIZATION_PK    |    36 |   144 |       |     1   (0)| 00:00:01 |
|*  8 |        TABLE ACCESS FULL          | SP_ROLES_ORGANIZATION       |    19 |   133 |       |     3   (0)| 00:00:01 |
|   9 |      VIEW                         |                             | 12968 |   227K|       |  7728   (1)| 00:01:33 |
|  10 |       HASH GROUP BY               |                             | 12968 |   455K|       |  7728   (1)| 00:01:33 |
|* 11 |        HASH JOIN                  |                             |   411K|    14M|       |  7716   (1)| 00:01:33 |
|  12 |         VIEW                      | index$_join$_006            | 12968 |   126K|       |    60   (2)| 00:00:01 |
|* 13 |          HASH JOIN                |                             |       |       |       |            |          |
|  14 |           INDEX FAST FULL SCAN    | PK_SP_ORGANIZATION          | 12968 |   126K|       |    36   (0)| 00:00:01 |
|  15 |           INDEX FAST FULL SCAN    | IND_SP_ORGANIZATION_ID_UNIQ | 12968 |   126K|       |    38   (0)| 00:00:01 |
|  16 |         VIEW                      |                             |   382K|  9716K|       |  7655   (1)| 00:01:32 |
|  17 |          SORT UNIQUE              |                             |   382K|  9832K|    12M|  7655   (1)| 00:01:32 |
|  18 |           UNION-ALL               |                             |       |       |       |            |          |
|* 19 |            HASH JOIN              |                             |   368K|  9724K|       |  4844   (1)| 00:00:59 |
|  20 |             VIEW                  | index$_join$_008            | 12968 |   126K|       |    60   (2)| 00:00:01 |
|* 21 |              HASH JOIN            |                             |       |       |       |            |          |
|  22 |               INDEX FAST FULL SCAN| PK_SP_ORGANIZATION          | 12968 |   126K|       |    36   (0)| 00:00:01 |
|  23 |               INDEX FAST FULL SCAN| IND_SP_ORGANIZATION_ID_UNIQ | 12968 |   126K|       |    38   (0)| 00:00:01 |
|* 24 |             HASH JOIN             |                             |   368K|  6122K|  7568K|  4783   (1)| 00:00:58 |
|* 25 |              INDEX FAST FULL SCAN | IDX_LNK_ORGANIZATION_GUID   |   368K|  3241K|       |   416   (1)| 00:00:05 |
|  26 |              TABLE ACCESS FULL    | T_ORGANIZATION              |   609K|  4759K|       |  3418   (1)| 00:00:42 |
|  27 |            INDEX FAST FULL SCAN   | LNK_ROLES_ORGANIZATION_PK   | 13872 |   108K|       |    11   (0)| 00:00:01 |
|* 28 |   HASH JOIN                       |                             | 12968 |  3507K|       |   181   (1)| 00:00:03 |
|  29 |    TABLE ACCESS FULL              | SP_ORGANIZATION_UNIQ        | 12074 |   955K|       |    75   (0)| 00:00:01 |
|  30 |    TABLE ACCESS FULL              | SP_ORGANIZATION             | 12968 |  2482K|       |   105   (0)| 00:00:02 |
-------------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - access("R"."ID"="O"."ID")
   4 - access("O"."ID_ROLE_ORGANIZATION"="ROLES"."ID")
   8 - filter("R"."ID_PARENT" IS NOT NULL)
  11 - access("O"."ID_UNIQ"="P2"."ID_UNIQ")
  13 - access(ROWID=ROWID)
  19 - access("O"."ID"="L"."ID_SP_ORGANIZATION")
  21 - access(ROWID=ROWID)
  24 - access("T"."ID"="L"."ID_T_ORGANIZATION")
  25 - filter("L"."ID_SP_ORGANIZATION" IS NOT NULL)
  28 - access("OU"."ID"="O"."ID_UNIQ")
Вижу что много времени идет
|  26 |              TABLE ACCESS FULL    | T_ORGANIZATION              |   609K|  4759K|       |  3418   (1)| 00:00:42 |
Странно индексы ЕСТЬ на поля:
ID_ROLE_ORGANIZATION
ID (PK)

Пробовал использовать хинты, чтобы использовались индексы. Но план не изменился.
Может подскажите что-то подправить. А может запрос и уже оптимальный.
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
А что, запрос вот так безо всяких ограничивающих условий и используется? Все 20К записей каждый раз и нужны? Странновато...

Вообще без твоей БД (как минимум полной схемы и тестовых данных сравнимого объёма) сложно сказать как оно будет лучше - если статистика собрана и она актуальна, то сервер намеренно не использует индексы - считает что лучше таблицу целиком читать, чем из 2-х индексов соорудить типа-таблицу (как чуть выше он делает для SP_ORGANIZATION - там из 2 индексов по сути восстанавливается таблица - при том делает он это 2 раза, как видно по плану - строки 12-15 и 20-23).
Начинать оптимизацию стоит с анализа логики запроса и устранения формальных косяков - например я не понимаю в чём логика использования LEFT JOIN если потом идёт WHERE t.ID_ROLE_ORGANIZATION IS NOT NULL, которое по сути превращает соединения в INNER JOIN... Мелочь, но для понимания логики запроса она тоже важна...
Странноватый подзапрос к sp_roles_organization - если там иерархия, то не совсем корректно так её разворачивать - так можно получить только вложенные непосредственно в роль роли - через 1 уровень уже "не проскочит" (но может там так и надо - может там иерархия всего на 2 уровня то и есть - кто ж знает...)

Вариант "в лоб" - сделать индекс по T_ORGANIZATION(ID, ID_ROLE_ORGANIZATION) - но не факт что он будет достаточно компактным, и что его использование вместо таблицы даст большой выигрыш.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
ВладимирС
Автор

Сообщений: 1693
Дата регистрации: 03.11.2005
Большое спасибо за комментарии...
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
ВладимирС
Автор

Сообщений: 1693
Дата регистрации: 03.11.2005
Igor Korolyov
А что, запрос вот так безо всяких ограничивающих условий и используется? Все 20К записей каждый раз и нужны? Странновато...
Да... просто я начал анализировать построенную начальником вьюху... она выдает действительно много записей... Он меня и попросил проанализировать работу вьюхи...
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
В том то и дело что бессмысленно оптимизировать "полную выборку", если как правило работает запрос вынимающий лишь небольшое подмножество - ты сделаешь только хуже, ускорив "запрос всего".
Не использует пару индексов, т.к. оценивает затраты на их полное чтение плюс соединение в памяти больше чем не полное чтение самой таблицы.

ВладимирС
--WHERE t.ID_ROLE_ORGANIZATION IS NOT NULL /* Здесь это сравнение не нужно, т.к. T_ORGANIZATION.ID_ROLE_ORGANIZATION NOT NULL */
Тут ты сильно не прав в логике работы SQL...
Эта таблица стоит в LEFT JOIN -> в результат запроса попадают записи из ZAGS_NSI.SP_ORGANIZATION для которых нет соответствия в LNK_ORGANIZATION_GUID, либо дальше по цепочке в T_ORGANIZATION -> данное условие как раз такие "левые" записи и отбрасывает. Если поле имеет констрейн NOT NULL, то выкинуть условие можно лишь после замены LEFT JOIN на INNER JOIN.
WITH SP_ORGANIZATION
AS (SELECT 101 ID, 1001 ID_UNIQ FROM DUAL
UNION ALL
SELECT 103 ID, 1003 ID_UNIQ FROM DUAL
UNION ALL
SELECT 104 ID, 1004 ID_UNIQ FROM DUAL),
LNK_ORGANIZATION_GUID
AS (SELECT 101 ID_SP_ORGANIZATION, 1 ID_T_ORGANIZATION FROM DUAL
UNION ALL
SELECT 103 ID_SP_ORGANIZATION, 3 ID_T_ORGANIZATION FROM DUAL),
T_ORGANIZATION
AS (SELECT 1 ID, 9 ID_ROLE_ORGANIZATION FROM DUAL
UNION ALL
SELECT 2 ID, 8 ID_ROLE_ORGANIZATION FROM DUAL)
--Ver1
/*SELECT T.ID_ROLE_ORGANIZATION, O.ID_UNIQ
FROM SP_ORGANIZATION O
INNER JOIN LNK_ORGANIZATION_GUID L ON O.ID = L.ID_SP_ORGANIZATION
INNER JOIN T_ORGANIZATION T ON T.ID = L.ID_T_ORGANIZATION*/
--Ver2
/*SELECT T.ID_ROLE_ORGANIZATION, O.ID_UNIQ
FROM SP_ORGANIZATION O
LEFT JOIN LNK_ORGANIZATION_GUID L ON O.ID = L.ID_SP_ORGANIZATION
LEFT JOIN T_ORGANIZATION T ON T.ID = L.ID_T_ORGANIZATION
WHERE T.ID_ROLE_ORGANIZATION IS NOT NULL*/
--Ver3
SELECT T.ID_ROLE_ORGANIZATION, O.ID_UNIQ
FROM SP_ORGANIZATION O
LEFT JOIN LNK_ORGANIZATION_GUID L ON O.ID = L.ID_SP_ORGANIZATION
LEFT JOIN T_ORGANIZATION T ON T.ID = L.ID_T_ORGANIZATION;
Сравни три этих запроса.
Другое дело, что далее над этим подзапросом после всяких группировок и соединений используют INNER JOIN по этому самому полю - что по сути опять выкидывает возможные null значения - но в любом случае это "неаккуратненько"
Кстати в этом куске идёт UNION где в одной части вынимаются ID_UNIQ из SP_ORGANIZATION, а во второй какие-то ID_SP_ORGANIZATION из LNK_ROLES_ORGANIZATION - судя по имени поля это нечто ссылающееся на ID из SP_ORGANIZATION - это несколько странно и будет иметь смысл лишь в том случае, если поле ID_UNIQ содержит те же по смыслу ключи что и поле ID. Не в смысле что они совпадают для всех записей, а, скажем ID ссылается на ID_UNIQ или наоборот в рамках данной таблицы (что-то типа иерархии организаций, или просто "код главной организации"). Если ключи не пересекаются, то значит с логикой такого запроса очень большие проблемы


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
ВладимирС
Автор

Сообщений: 1693
Дата регистрации: 03.11.2005
Igor Korolyov
В том то и дело что бессмысленно оптимизировать "полную выборку", если как правило работает запрос вынимающий лишь небольшое подмножество - ты сделаешь только хуже, ускорив "запрос всего".
Не использует пару индексов, т.к. оценивает затраты на их полное чтение плюс соединение в памяти больше чем не полное чтение самой таблицы.
Т.е. по твоему индекс
CREATE INDEX ZAGS_DATA1.IDX_T_ORGANIZATION_01 ON ZAGS_DATA1.T_ORGANIZATION
(ID, ID_ROLE_ORGANIZATION);
ЛИШНИЙ... ?
Но заметим, план выполнения изменился в лучшую сторону... И этот индекс как раз ускоряет выборку данных из вьюхи...
Кстати на тестовом нашем сервере, где данных по T_ORGANIZATION больше (т.к. там мусора много), запрос при созданном индексе выполняется в 2 с лишним раза быстрее...

Igor Korolyov
...
ВладимирС
--WHERE t.ID_ROLE_ORGANIZATION IS NOT NULL /* Здесь это сравнение не нужно, т.к. T_ORGANIZATION.ID_ROLE_ORGANIZATION NOT NULL */
Тут ты сильно не прав в логике работы SQL...
Ты прав... из-за LEFT JOIN
...
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
ВладимирС
Автор

Сообщений: 1693
Дата регистрации: 03.11.2005
Igor Korolyov
WITH SP_ORGANIZATION
AS (SELECT 101 ID, 1001 ID_UNIQ FROM DUAL
UNION ALL
SELECT 103 ID, 1003 ID_UNIQ FROM DUAL
UNION ALL
SELECT 104 ID, 1004 ID_UNIQ FROM DUAL),
LNK_ORGANIZATION_GUID
AS (SELECT 101 ID_SP_ORGANIZATION, 1 ID_T_ORGANIZATION FROM DUAL
UNION ALL
SELECT 103 ID_SP_ORGANIZATION, 3 ID_T_ORGANIZATION FROM DUAL),
T_ORGANIZATION
AS (SELECT 1 ID, 9 ID_ROLE_ORGANIZATION FROM DUAL
UNION ALL
SELECT 2 ID, 8 ID_ROLE_ORGANIZATION FROM DUAL)
--Ver1
/*SELECT T.ID_ROLE_ORGANIZATION, O.ID_UNIQ
FROM SP_ORGANIZATION O
INNER JOIN LNK_ORGANIZATION_GUID L ON O.ID = L.ID_SP_ORGANIZATION
INNER JOIN T_ORGANIZATION T ON T.ID = L.ID_T_ORGANIZATION*/
--Ver2
/*SELECT T.ID_ROLE_ORGANIZATION, O.ID_UNIQ
FROM SP_ORGANIZATION O
LEFT JOIN LNK_ORGANIZATION_GUID L ON O.ID = L.ID_SP_ORGANIZATION
LEFT JOIN T_ORGANIZATION T ON T.ID = L.ID_T_ORGANIZATION
WHERE T.ID_ROLE_ORGANIZATION IS NOT NULL*/
--Ver3
SELECT T.ID_ROLE_ORGANIZATION, O.ID_UNIQ
FROM SP_ORGANIZATION O
LEFT JOIN LNK_ORGANIZATION_GUID L ON O.ID = L.ID_SP_ORGANIZATION
LEFT JOIN T_ORGANIZATION T ON T.ID = L.ID_T_ORGANIZATION;
Сравни три этих запроса.
Другое дело, что далее над этим подзапросом после всяких группировок и соединений используют INNER JOIN по этому самому полю - что по сути опять выкидывает возможные null значения - но в любом случае это "неаккуратненько"
Спасибо...
Igor Korolyov
...
Кстати в этом куске идёт UNION где в одной части вынимаются ID_UNIQ из SP_ORGANIZATION, а во второй какие-то ID_SP_ORGANIZATION из LNK_ROLES_ORGANIZATION - судя по имени поля это нечто ссылающееся на ID из SP_ORGANIZATION - это несколько странно и будет иметь смысл лишь в том случае, если поле ID_UNIQ содержит те же по смыслу ключи что и поле ID. Не в смысле что они совпадают для всех записей, а, скажем ID ссылается на ID_UNIQ или наоборот в рамках данной таблицы (что-то типа иерархии организаций, или просто "код главной организации"). Если ключи не пересекаются, то значит с логикой такого запроса очень большие проблемы
Да в таблицах БД, так все (по моему) запутано... Разбираться трудно... А начальник из себя строит высокого... Спросишь, а он в ответ, что не можешь разобраться ? (Он понимает, что участия в этом проекте БД я не занимался...)
Ratings: 0 negative/0 positive
Re: Oracle. Администрирование.
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
ВладимирС
Т.е. по твоему индекс ...ЛИШНИЙ... ?
Нет, но он сугубо "оптимизационный". При том конкретно такой индекс делает "логически лишним" индекс по ID - правда его нужно было ещё и UNIQUE для полного счастья сделать Хотя с точки зрения оптимизации бывает полезно держать "лишние" индексы - особенно если таблица очень большая и сравнительно статичная - т.е. не претерпевает множества модификаций во время работы системы.
ВладимирС
Но заметим, план выполнения изменился в лучшую сторону... И этот индекс как раз ускоряет выборку данных из вьюхи...
Ну для того он и делалася то Надо оценивать размеры сегментов - по логике для "нормальной" таблицы индекс по 2-м полям должен быть заметно меньше по размеру чем собственно сегмент данных. Правда и читается он чуть по другому - т.е. один лишь "размер" критерий недостаточный.

Для "разбора логики" одной лишь БД маловато - хотя имеющиеся констрейны ссылочной целостности (foreign key) и говорят многое о взаимосвязи данных... Но без постановщика знающего предметную область всё равно не обойтись.


------------------
WBR, Igor
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 9 (Гостей: 9)

© 2000-2024 Fox Club 
Яндекс.Метрика