Жутко долго выполняется скрипт с UpdateQuery

Firebird2.0, CRM X25 3.0.4.112

if (Assigned(RightsDataset)) {
var UQ = Services.GetNewItemByUSI('uq_Rights');
RightsDataset.DisableEvents();
EnableDatasetFilters(RightsDataset, false, 'ID');
EnableDatasetFilters(RightsDataset, false, 'UserContactID');
ApplyDatasetFilter(RightsDataset, 'RecordID', ID, true);
ApplyDatasetFilter(RightsDataset, 'AdminUnitID', UsID, true);
RightsDataset.Open();
if (IsDatasetEmpty(RightsDataset)) {
AddAccessRecord2(RightsDataset, ID, UsID, CanRead, CanWrite,
CanDelete, CanChangeAccess, CanDel);
} else {
var RightID=RightsDataset.ValAsGUID('ID');
if (!IsEmptyValue(RightID)) {
//UpdateAccessRecord2(UQ, RightID, CanRead, CanWrite,
//CanDelete, CanChangeAccess, CanDel);
}
}
RightsDataset.Close();
RightsDataset.EnableEvents();
AdminUnitDataset.GotoNext();
}

function AddAccessRecord2(Dataset, RecordID, AdminUnitID, CanRead,
        CanWrite, CanDelete, CanChangeAccess, CanDel) {
        var FieldValues = new Array (RecordID, AdminUnitID, CanRead,
                CanWrite, CanDelete, CanChangeAccess, CanDel);
        var FieldNames = new Array ('RecordID', 'AdminUnitID', 'CanRead',
                'CanWrite',     'CanDelete', 'CanChangeAccess', 'CanDel');
    AppendRecordInDataset(Dataset, FieldNames, FieldValues);
}
function UpdateAccessRecord2(UpdateQuery, ID, CanRead,
        CanWrite, CanDelete, CanChangeAccess, CanDel) {
        var FieldValues = new Array (CanRead,
                CanWrite, CanDelete, CanChangeAccess, CanDel);
        var FieldNames = new Array ('CanRead',
                'CanWrite',     'CanDelete', 'CanChangeAccess', 'CanDel');
    UpdateRecordField(UpdateQuery, ID, FieldNames, FieldValues);
}

AddAccessRecord2 выполняется доли секунды, а UpdateAccessRecord2 - секунд 10-15.
Почему так? Нельзя ли как-то быстро обновлять поля?

Нравится

13 комментариев

Точную причину назвать не могу. Рекомендую более детально отладить работу функции UpdateRecordField, возможно, причина задержек вовсе не в БД, а в коде конфигурации.
Для отладки по шагам и оценкой времени выполнения можно после каждой строки выводить в лог некоторое сообщение, при выводе сообщения осуществляется вывод точного времени, поэтому можно проанализировать, сколько времени выполнялась та или иная строка кода.

Здравствуйте!
1. Что собой представляет uq_Rights?
2. Какую таблицу Вы обновляете? Нет ли на ней триггеров?
3. Под администратором тормозит или под пользователем?

1.

<?xml version="1.0" encoding="UTF-8"?>
<Service UID="CADAB9769B404DE69538D1DE3624501E" USI="X15\Workspaces\Tasks\General\Main Grid\uq_Rights" ServiceTypeCode="UpdateQuery" Caption="uq_Rights" TableUSI="tbl_TaskRight">
	<Parameters>
		<Item Name="RecordID" UID="39D7D0CF7B534955BF28395DC75612E2" DataType="0" Value_ValueType="0">
		</Item>
		<Item Name="AdminUnitID" UID="367734510F9B4346B2447DF3E35B4C24" DataType="0" Value_ValueType="0">
		</Item>
		<Item Name="ID" UID="F64EDC061DD045AF86F9470A741D8ACB" DataType="7" Value_ValueType="0">
		</Item>
	</Parameters>
	<Filters Code="Where" Type="Filters">
		<Item Code="RecordID" UID="4AE62F99FFF9459F92FD48FDFCB2AC49" Type="CompareFilter" IsEnabled="False" ExpressionTypeCode="FieldFilterExpression" ValueExpressionTypeCode="ParamFilterExpression">
			<TestExpression Type="FieldFilterExpression" FieldSQLName="RecordID" FieldTableUSI="tbl_TaskRight" TableAlias="tbl_TaskRight">
			</TestExpression>
			<ValueExpression Type="ParamFilterExpression" ParameterName="RecordID">
			</ValueExpression>
		</Item>
		<Item Code="AdminUnitId" UID="529036173DD14F0E812718D91146D715" Type="CompareFilter" IsEnabled="False" ExpressionTypeCode="FieldFilterExpression" ValueExpressionTypeCode="ParamFilterExpression">
			<TestExpression Type="FieldFilterExpression" FieldSQLName="AdminUnitID" FieldTableUSI="tbl_TaskRight" TableAlias="tbl_TaskRight">
			</TestExpression>
			<ValueExpression Type="ParamFilterExpression" ParameterName="AdminUnitID">
			</ValueExpression>
		</Item>
		<Item Code="ID" UID="BE13FA4486F8426CA996C994D8C03654" Type="CompareFilter" IsEnabled="False" ExpressionTypeCode="ParamFilterExpression" ValueExpressionTypeCode="ParamFilterExpression">
			<TestExpression Type="ParamFilterExpression" ParameterName="ID">
			</TestExpression>
			<ValueExpression Type="ParamFilterExpression" ParameterName="ID">
			</ValueExpression>
		</Item>
	</Filters>
	<ColumnsValues>
		<Item Name="CanRead" UID="8219770BBAA74F4F94E1C53038C7C06C" DataType="5" Value_ValueType="0" ParameterName="CanRead">
		</Item>
		<Item Name="CanWrite" UID="7DE190FF4E1848AC8158E58280CC5AF9" DataType="5" Value_ValueType="0" ParameterName="CanWrite">
		</Item>
		<Item Name="CanDelete" UID="F20E24A20C0140B1973FCE2F6A55471F" DataType="5" Value_ValueType="0" ParameterName="CanDelete">
		</Item>
		<Item Name="CanChangeAccess" UID="212A0A7186884B92B440048A93451A29" DataType="5" Value_ValueType="0" ParameterName="CanChangeAccess">
		</Item>
		<Item Name="CanDel" UID="17CD7A99F97F4326BABAA6BE2EB8272F" DataType="5" Value_ValueType="0" ParameterName="CanDel">
		</Item>
	</ColumnsValues>
</Service>

2. Обновляю в данном случае tbl_TaskRight. А так собираюсь обновлять любую tbl_...Right. Триггеров нет.
3. И под администратором и под пользователем.

1. Сколько записей в tbl_TaskRight?
2. Можете выполнить в IBExpert, заполнив параметры:

UPDATE "tbl_TaskRight"
SET "CanRead" = :CanRead,
    "CanWrite" = :CanWrite,
    "CanDelete" = :CanDelete,
    "CanChangeAccess" = :CanChangeAccess
WHERE("tbl_TaskRight"."ID" = :ID);

Сколько он будет выполняться?

1. 7400
2.

UPDATE "tbl_TaskRight"
SET "CanRead" = 1,
    "CanWrite" = 1,
    "CanDelete" = 1,
    "CanChangeAccess" = 1,
    "CanDel" = 1
WHERE "tbl_TaskRight"."ID" = '{00E928BC-AF61-4FE5-8E61-2ADAC846D671}';

Время выполнения запроса = 109ms

Значит где-то тормозит конфигурация. Как Вы определили что "тормозит" именно UpdateRecordField?
И еще:
В ф-ции UpdateRecordField там где идет Execute:

...
Log.Write(1, Connector.DBEngine.GetUpdateQuerySQLText(UpdateQuery));
UpdateQuery.Execute();
...

И покажите какой запрос идет.

А что за поле CanDel?

[08.09.12 13.35.23.240]	(W)	До UpdateAccessRecord2
[08.09.12 13.35.23.255]	(W)	UPDATE "tbl_TaskRight"
	SET "CanRead" = :CanRead,
	"CanWrite" = :CanWrite,
	"CanDelete" = :CanDelete,
	"CanChangeAccess" = :CanChangeAccess,
	"CanDel" = :CanDel
WHERE
	('{F0FD6878-9F79-4273-9D73-7B63FFDDD08B}' = :ID)
[08.09.12 13.35.27.772]	(W)	После UpdateAccessRecord2
[08.09.12 13.35.27.803]	(W)	До UpdateAccessRecord2
[08.09.12 13.35.27.803]	(W)	UPDATE "tbl_TaskRight"
	SET "CanRead" = :CanRead,
	"CanWrite" = :CanWrite,
	"CanDelete" = :CanDelete,
	"CanChangeAccess" = :CanChangeAccess,
	"CanDel" = :CanDel
WHERE
	('{BAC3ABC0-C71A-4DC2-9874-565A9D4B94BB}' = :ID)
[08.09.12 13.35.32.445]	(W)	После UpdateAccessRecord2

CanDel такое же булевское поле как и остальные Can...

Проблема решена.
В UpdateQuery было условие параметр = параметр
:)

Сразу не заметил - у Вас ошибка в фильтре ID. В каждой части у Вас параметр причем один и тот же. И Вы обновляли все(!) записи таблицы tbl_TaskRight. Надо одну из частей заменить на поле tbl_TaskRight.ID
А зачем это поле CanDel? В таблицы прав строго не рекомендуется вносить изменения, т.к. при обновлении версий и т.п. Вы потеряте его, даже более того - при снятии/установке в таблице tbl_Task - Администрируется по записям.

3.0 дальше развиваться не будет.
А переходить на новую версию мы не собираемся, так как это требует покупки лицензий и внесение изменений в базовую конфигурацию снова.
CanDel нужно для того, чтобы указать может ли владелец записи удалять данную запись прав доступа.
Нам не нужно чтобы сотрудник мог удалять из доступа своего начальника.
И кроме как внесение изменений в tbl_TaskRight я не придумал решения.

Ну можно было использовать CanChangeAccess - она в принципе почти для этого и придумывалась. В Вашем случае можно было ее анализировать.

Не совсем так.
Мне нужно было убрать только возможность удаления права чтения.
Остальные права автор может менять как ему нужно.

Но это в принципе не важно.
Внесены также изменения в большое количество сервисов.

Показать все комментарии