Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Resource manager ограничение параллельных серверов

Задача.
БД Oracle 11.2.0.4 EE
Необходимо запретить определенным учетным записям запускать больше 20 параллельных серверов на всех.
Как я понимаю, Oracle Resource Manager с этим должен справиться.
- PARALLEL_TARGET_PERCENTAGE.
Эта директива выставляет лимит в процентах от параметра PARALLEL_SERVERS_TARGET.

Тестовая среда:
На сервере parallel_servers_target=120
Чтобы получить нужный лимит, выставляю значение директивы PARALLEL_TARGET_PERCENTAGE=16

Создаю две учетные записи.
usert1 - владелец объектов (таблицы)
usert2 - учетка которую нужно ограничить в ресурсах
+
SQL> show parameter PARALLEL_SERVERS_TARGET

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
parallel_servers_target              integer     120
SQL> show parameter PARALLEL_DEGREE_POLICY

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
parallel_degree_policy               string      AUTO
SQL>

SQL> CREATE USER USERT1 IDENTIFIED BY usert1;

User created.

SQL> GRANT CREATE SESSION TO USERT1;

Grant succeeded.

SQL>
SQL> CREATE USER USERT2 IDENTIFIED BY usert2;

User created.

SQL> ALTER USER USERT2 QUOTA UNLIMITED ON USERS;

User altered.

SQL> GRANT CREATE SESSION TO USERT2;

Grant succeeded.

SQL>


Создаю тестовую таблицу в схеме usert1, наполняю данными и даю грант пользователю usert2.
+

SQL> CREATE TABLE USERT1.T1 AS SELECT * FROM DBA_OBJECTS;

Table created.

SQL>
SQL> begin
  2      For IDS in 1..10
  3      loop
  4          insert into USERT1.T1
  5          select *
  6            from USERT1.T1;
  7      end loop;
  8      commit;
  9  end;
 10  /

PL/SQL procedure successfully completed.

SQL>
SQL> grant select on USERT1.T1 to USERT2;

Grant succeeded.

SQL>

А теперь создаю ресурсный план, группу, директивы.
Активирую ресурсный план.
Добавляю пользователя USERT2 в нужную ресурсную группу.
+
SQL> begin
  2    DBMS_RESOURCE_MANAGER.CLEAR_PENDING_AREA();
  3    DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA();
  4    DBMS_RESOURCE_MANAGER.CREATE_PLAN (
  5        plan                         => 'TEST_LIMIT_PLAN'
  6       ,comment                      => '');
  7    DBMS_RESOURCE_MANAGER.CREATE_CONSUMER_GROUP (
  8        consumer_group               => 'TEST_LIMIT_GROUP'
  9       ,comment                      => '');
 10    DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE (
 11        plan                         => 'TEST_LIMIT_PLAN'
 12       ,group_or_subplan             => 'OTHER_GROUPS'
 13       ,comment                      => ''  );
 14    DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE (
 15        plan                         => 'TEST_LIMIT_PLAN'
 16       ,group_or_subplan             => 'TEST_LIMIT_GROUP'
 17       ,parallel_target_percentage   => 16
 18       ,comment                      => ''  );
 19    DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA();
 20    DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA();
 21  end;
 22  /

PL/SQL procedure successfully completed.

SQL>
SQL> ALTER SYSTEM SET RESOURCE_MANAGER_PLAN = TEST_LIMIT_PLAN;

System altered.

SQL>
SQL> BEGIN
  2    DBMS_RESOURCE_MANAGER.create_pending_area();
  3    DBMS_RESOURCE_MANAGER_PRIVS.GRANT_SWITCH_CONSUMER_GROUP('USERT2','TEST_LIMIT_GROUP',FALSE);
  4    DBMS_RESOURCE_MANAGER.SET_INITIAL_CONSUMER_GROUP('USERT2','TEST_LIMIT_GROUP');
  5    DBMS_RESOURCE_MANAGER.submit_pending_area();
  6  END;
  7  /

PL/SQL procedure successfully completed.

SQL>

Если я все правильно понимаю, этого должно быть достаточно, чтобы ресурсный менеджер работал.
Параллельно я подключаюсь под учеткой usert2 и запускаю запрос с количеством параллельных серверов превышающего выставленный лимит:
SQL> select /*+ PARALLEL(25) */ owner, object_name, count(*) from USERT1.T1 group by owner, object_name;

И пока этот запрос работает в первой сессии смотрю количество параллельных серверов от этой учетки
SQL> select s.username, s.module, count(*)
  2    from v$session s, v$px_session p
  3  where s.sid = p.sid and username = 'USERT2'
  4  group by  s.username, s.module;

USERNAME                       MODULE                                                             COUNT(*)
------------------------------ ---------------------------------------------------------------- ----------
USERT2                         SQL*Plus                                                              51

SQL>

Ограничение ресурсного менеджера не сработало.
Можете подсказать, что я неправильно делаю?
Ответ:
SeaGate
led_yurik,


Managing Resources with Oracle Database Resource Manager Parallel Target Percentage
If a consumer group does not have any parallel statements running within an Oracle RAC database, then the first parallel statement is allowed to exceed the limit specified by PARALLEL_TARGET_PERCENTAGE.

Хоть речь тут про RAC, это применимо и к не-RAC. Как обычно, сделали через известное место и прикрылись документацией.
Соответственно, одной сессии мало. Ограничение начнет работать со второй сессии.
Чтобы ограничить сверху в таком сценарии, с учетом замечания из документации о превышении порога для первого statement, нужно еще parallel_degree_limit_p1 задать.


SQL> begin
  2    DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA();
  3    DBMS_RESOURCE_MANAGER.UPDATE_PLAN_DIRECTIVE (
  4        plan                         => 'TEST_LIMIT_PLAN'
  5       ,group_or_subplan             => 'TEST_LIMIT_GROUP'
  6       ,new_parallel_degree_limit_p1 => 10);
  7    DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA();
  8    DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA();
  9  end;
 10  /
PL/SQL procedure successfully completed.

После этого запускаю несколько параллельных сессий запрос из под учетки usert2.
И смотрю количество параллельных серверов
SQL> select s.username, s.module, count(*)
  2    from v$session s, v$px_session p
  3  where s.sid = p.sid and username = 'USERT2'
  4  group by  s.username, s.module;

USERNAME                       MODULE                                                             COUNT(*)
------------------------------ ---------------------------------------------------------------- ----------
USERT2                         SQL*Plus                                                              21

SQL>

Все работает! но похоже на чудо))

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

Буду внимательней проверять на реальных данных!

Спасибо большое, а то я уже начал отчаиваться.
Вопрос: Параллельные запросы

Помогите прояснить следующее:
Имеется две трассировки 10053, уровень 12, БД 11.2.0.4

В первой есть такое:

***************************************
PARAMETERS USED BY THE OPTIMIZER
********************************
*************************************
PARAMETERS WITH ALTERED VALUES
******************************
Compilation Environment Dump
------------------------
parallel_autodop = 1


В второй есть такое:

PARAMETERS USED BY THE OPTIMIZER
********************************
*************************************
PARAMETERS WITH ALTERED VALUES
******************************
parallel_hinted = serial


Запросы одинаковые, вида: запросX union запросY union запросQ и т.д
с одной лишь разницей, что во втором случае два запроса(допустим запросF и запросH) имеют хинт /*+ noparallel*/.

В первом случае имеем «параллельный» во втором «последовательный» план.

Вопрос:
1. Должен ли оптимизатор выполнить часть запроса в параллели, а часть последовательно если где-то в запросах/подзапросах есть хинт /*+ noparallel*/?
2. Что это за параметры: parallel_hinted и parallel_autodop?
Ответ:
usolcew
Kamael,

>> 1. Должен ли оптимизатор выполнить часть запроса в параллели, а часть последовательно если где-то в запросах/подзапросах есть хинт /*+ noparallel*/?

нет, хинт /*+ noparallel*/ в любой части запроса обычно отключает параллельное выполнение на уровне всего запроса, и вы видите в трейсе изменение параметра для всего запроса:

*************************************
PARAMETERS WITH ALTERED VALUES
******************************
parallel_hinted = serial


, который собственно и отражает степень хинтованности запроса в части параллельного выполнения

параметр parallel_autodop имхо логически (1/0) отражает использование autodop в запросе, смотрите секцию

**************************
Automatic degree of parallelism (AUTODOP)
**************************

Да, всё оно так, и в секции Automatic degree of parallelism (AUTODOP) указан disable.
Это поведение где-то описано, или по крупицам искать/тестировать?

Вот ещё вопрос про параллеьность, кусок трейса _px_trace:

Parallelism disabled at runtime because forced serial at compilation time
qerpxStart [ 20630/ 60]
rwsrid:40 pxid:3 qbas:67934:err:0
START no parallel command type
qertqoStart [ 20630/ 0]

kxfqd : 0x1661f53e38
kxfqdtqi : 1
kxfqdcc : 0x14 TQ: from slave set 1 to QC
kxfqdpty : 4
kxfqdsmp : 90 number of samples
kxfqdflg : 0x5000000
/KXFQDF_FASTENQ/KXFQDF_PBIN
kxfqdstart: 0 partitioning column offset
kxfqdfmt : TQ format
kxfqfnco : 5 number of TQ columns
kxfqfnky : 0 number of key columns
kxfqfnpcol: 0 number of partitioning columns
TQ column kxfqcbfl kxfqcdty kxfqcflg kxfqcplen
kxfqfcol[ 0]: 4 23 0x0 4
kxfqfcol[ 1]: 0 23 0x80 0
kxfqfcol[ 2]: 1 23 0x0 1
kxfqfcol[ 3]: 96 23 0x0 96
kxfqfcol[ 4]: 0 23 0x0 0
klcliti [ 20630/ 0]
tobjn:-39858490, tobjv:1
qertqiStart [ 20630/ 0]
dfo=0 passthru
qertqoStart [ 20630/ 0]

kxfqd : 0x1661f546c0
kxfqdtqi : 0
kxfqdcc : 0x21 TQ: from slave set 2 to slave set 1
kxfqdpty : 2
kxfqdsmp : 90 number of samples
kxfqdflg : 0x21000080
/KXFQDFPAGG/KXFQDF_FASTENQ
kxfqdstart: 0 partitioning column offset
kxfqdfmt : TQ format
kxfqfnco : 3 number of TQ columns
kxfqfnky : 2 number of key columns
kxfqfnpcol: 0 number of partitioning columns
TQ column kxfqcbfl kxfqcdty kxfqcflg kxfqcplen
kxfqfcol[ 0]: 4000 1 0x0 4000
kxfqfcol[ 1]: 16 1 0x200 16
kxfqfcol[ 2]: 14 209 0x0 14
kxfrfir [ 20630/ 0]

Это можно как то перевести в читаемый вид?
Вопрос: чем повысить стоимость запроса, чтобы оптимизатор выбрал параллельный план?

SQL Azure. Чем повысить стоимость запроса, чтобы оптимизатор выбрал параллельный план?


автор
DBCC command 'SETCPU WEIGHT' is not supported in this version of SQL Server
Ответ: Владислав Колосов,

примерно так и сделал. завелась телега. (запрос бессмысленный, там сложная формула считается, жрущая CPU, цель была вычислять ее на каждом потоке посмотрел также распределение строк по потокам - почти равномерно, и scalar operator'ы в параллельной зоне, меня такое устроит и ожур показует CPU load 99%). выяснить примерно количество ядер на тарифе P11 (получается ~8). и сравнить во сколько раз медленнее чем железяки (ну хоть как-нибудь сравнить).
Вопрос: Сложная головоломка по легким математическим вычислениям

Есть столбец "стоимость дизельного топлива" эта стоимость постоянно скачет (думаю Вы заметили) Вопрос: необходимо чтобы система при вычислениях брала только последнее изменение стоимости д/т в солбце "стоимость дизельного топлива". Например: необходимо умножить коэффициент 0,69 на последнее изменение этого столбца. КАК это сделать!!!
Ответ:
Сообщение от cap7
необходимо чтобы система при вычислениях брала только последнее изменение стоимости д/т в солбце "стоимость дизельного топлива
Это неточное ТЗ. Например, для отчета за год, надо брать реальную цену для каждой даты. Она будет отличаться от последней введенной. Соответственно, надо опираться именно на дату. Удобно это сделать в функции
Код Visual Basic
1
2
3
4
5
6
7
Public Function CurrentPrice(DatePrice)
  Dim s
  s="select Top 1 [стоимость дизельного топлива] from Таблица " _
  & "where [ПолеДаты]<=" Format(DatePrice, "\#mm\/dd\/yyyy\#") _
  & " order by [ПолеДаты] Desc"
  CurrentPrice=Currentdb.Openrecordset(s).Fields(0)
End Function
Этой функцией CurrentPrice можно пользоваться в запросах, формах, отчетах. При вызове в параметр функции DatePrice подставлется требуемая дата. При заполнении формы это будет текущая дата
Вопрос: Оптимизация вычислений нескольких вычисляемых полей в таблице

Имеется таблица tbl_Group с полями Id, calc_0, calc_1, calc_2, calc_3, ... , calc_5

В этой таблице, согласно названию полей, все, кроме Id является вычисляемым и ссылается на соответствующие функции f_0, f_1, ... , f_5

Каждая функция обращается к таблице (на самом деле табличной функции от Id группы - строки tbl_Groups) fnc_Items и отображает количество элементов в таблице по различным условиям. То есть примерно это выглядит так:

f_0:
T-SQL
1
SELECT COUNT(*) FROM tbl_Items
f_1:
T-SQL
1
2
SELECT COUNT(*) FROM fnc_Items 
WHERE x > 0
f_2:
T-SQL
1
2
SELECT COUNT(*) FROM fnc_Items 
WHERE x BETWEEN 31 AND 60
и так далее.

Таким образом мы получаем, что для того, чтобы выбрать одну строку из таблицы tbl_Group, нам необходимо обратиться к 6-ти разным функциям, которые в свою очередь 6 раз получат таблицу из функции fnc_Items чтобы применить к ней своё условие.

Вопрос заключается в том, можно ли использовать какой либо механизм кэширования или оптимизации, чтобы вызывать на одну строку в селекте таблицу fnc_Items 1 раз, а уже к результату выбора обращаться 6 раз, а не все время пересчитывать табличную функцию на каждое вычисляемое поле.

Используется MSSQL Server 2012, Transact-SQL
Ответ:
Сообщение от alex-ttt
как эта временная таблица должна создаваться и уничтожаться
ээээ как бы все в документации есть
Вопрос: Добавление вычислений в запрос

Подскажите необходимо сосчитать количество людей в подчинение и вывести их список. Employees.ReportsTo указывает на id, того кому этот человек подчиняется. Получилось как-то так, но выводит пустые значения для count и Subordinates .

T-SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Select
Employees.LastName,
Employees.FirstName,
Region.RegionDescription,
count(case when Employees.ReportsTo=Employees.EmployeeID then 1 end) as Count_of_employees,
Subordinates = STUFF((
          SELECT ', ' + Employees.LastName
          FROM Employees
          WHERE Employees.ReportsTo = Employees.EmployeeID
          FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
from Employees 
left join EmployeeTerritories on 
Employees.EmployeeID=EmployeeTerritories.EmployeeID
left join Territories on 
EmployeeTerritories.TerritoryID=Territories.TerritoryID
left join Region on Territories.RegionID=Region.RegionID
group by Region.RegionDescription,Employees.LastName, Employees.FirstName
Ответ: Snopy27, по поводу кол-ва людей в подчинении: вместо
SQL
1
COUNT(CASE WHEN Employees.ReportsTo=Employees.EmployeeID THEN 1 END) AS Count_of_employees,
я бы написал подзапрос
SQL
1
(SELECT COUNT(e2.EmployeeID) FROM Employees e2 WHERE e2.ReportsTo = e1.EmployeeID) AS Count_of_employees,
, где e1 - алиас для таблицы Employees из внешнего запроса.
Вопрос: Вычисление даты и выплат

Здравствуйте!
Есть база данных. Необходимо определить количество выплат особым образом, которое прошло с некоторой определённой даты. Сделал с помощью вычисляемого поля так:
T-SQL
1
(datediff(month,Tel.[Дата подключения], getdate())
Таким образом я определил лишь разницу в месяцах, но не в выплатах, то есть полученные значения будут неточными. Есть два условия нахождения выплат:
1. Первая выплата происходит в день "Даты подключения";
2. Каждая последующая выплата должна происходить 20-го числа каждого месяца.
Хоть убейте, но не могу придумать то, как реализовать это в виде вычисляемого поля(
Ответ: всего лишь операция сложения жалкой единички с недостающими единичками
Вопрос: Часто ли вы сталкиваетесь с оптимизацией планов Oracle в параллельных запросах ?

Вопрос возник в связи с тем, что если по оптимизации обычных запросов некоторые люди на собеседовании еще отвечают, то по оптимизации параллельных запросов никто толком ничего сказать не может.

Я имею ввиду как определить Data Skew, в какой строке плана выполнения Data Skew, ограничения V$PQ_TQSTAT и т.д.

Если люди с этим не сталкивались, значит редко где используются параллельные запросы ?

P.S. У нас DWH на Exadata, поэтому часто используем и отлаживаем параллельные запросы
Ответ:
JJZ
значит Oracle parallel server нигде особо не используется
На всякий случай -- Oracle Parallel Server не имеет практически никакого отношения к Parallel Query
Вопрос: запрос на сверку (tsql)

Здравствуйте, буду благодарен, если кто нибудь поможет с запросом t sql.
Есть два набора данных, предположительно одинаковых, но ввиду изменений в бизнес-логике в новой версии фактические данные немного отличаются.

В старой версии:
Id LateDays Amount
1 0 1000
2 55 2500
3 0 500
4 10 3000
5 0 700

В новой версии:
Id LateDays Amount
2 55 2500
3 2 500
4 10 3000
5 0 900
6 0 2000

Необходимо написать запрос, который проведет сверку этих данных и выдаст все несоответствия в таком виде:
Id1 LateDays1 Amount1 Id2 LateDays2 Amount2
1 0 1000 NULL NULL NULL
3 0 500 3 2 500
5 0 700 5 0 900
NULL NULL NULL 6 0 2000
Ответ: PaulYoung,

Спасибо.
Вопрос: Работа с XML через TSQL

Добрый день.

Сразу оговорюсь, пока не силён в работе с XML.

Как создать XML следующего формата:


Обязательные данные 1 (тип INT)
Обязательные данные 2 (тип DATETIME)
Обязательные данные 3 (тип NVARCHAR)
Набор данных (
___произвольная строка 1
___произвольная строка 2
___произвольная строка 3
___произвольная строка n
)

как создать набор данных, вопросов не возникло:
SELECT 
  [Key], [Surname], [Name], [Middlename]
FROM
  [TestClient]      
FOR XML AUTO


но вот не могу понять как быть дальше, помогите разобраться?
Ответ:
Ken@t
ИгорьUUS,
XSD для этого


А как в запрос
SELECT 
  '1' "@attr1"
   ,548 "@attr2"
   ,GETDATE() "@attr3"
FOR XML path('root')

подсунуть xsd, первый атрибут string, второй int, третий datetime?