Показать сообщение отдельно
Старый 27.09.2007, 14:11   #20  
Голышев Михаил is offline
Голышев Михаил
Участник
 
106 / 10 (1) +
Регистрация: 03.07.2006
Цитата:
Сообщение от Dzemon Посмотреть сообщение
Дело в том, что на SQL версии, оператор FIND БЛОКИРУЕТ ТАБЛИЦУ, а GET и LOCKTABLE - нет.
Не верно.

FIND не блокирует таблицу, если текущий уровень изоляции транзакции READUNCOMMITTED.
Или в нотации Navision TRANSACTIONTYPE::Browse
Аналогично работает и GET.

Этот тип изоляции с которым запускается по умолчанию любой код (до первых изменений в базе данных, после этого уровень изоляции увеличивается.) Также с этим уровнем изоляции отображаются некоторые формы, например
Фин Журнал и Товарный Журнал. Можно также указать уровень изоляции в свойствах Report'ов (св-во TransactionType).

Как правильно заметил Raul, уровень изоляции можно принудительно повысить, применив LOCKTABLE.
При этом следующий вызов FIND или GET будет не с хинтом READUNCOMMITTED, а с хинтом UPDLOCK (что заблокирует набор возвращаемых записей).

------
В качестве ускорения учета, мы в компании предприняли много мер, вот некоторые из них, которые приходят на ум:
  • 1
    Учет надо разделить на несколько этапов:
    а) Предучетные заполнения (обновления полей, расчет цен и т.п. Всё что можно сохранить до учета)
    б) COMMIT
    в) Предучетные проверки (Все проверки, TESTFIELDы, ERRORы и прочее, что может "обломить" учет). Выносим это непосредственно перед учетом, чтобы код выполнялся в режиме READUNCOMMITTED (TRANSACTIONTYPE::Browse).
    Некоторые проверки продублированы как в предучетной фазе так и в основной. Это немного увеличивает нагрузку, зато не возникает блокирование\освобождение ресурсов и откатов транзакции.
    г) основной учет
  • 2
    Борьба с эскалацией блокировок.
    Как было сказано выше, sql всегда осуществляет блокировку на уровне строк таблицы (по ключам).
    Однако, есть таблицы, для которых это излишне. Некоторые можно блокировать на уровне страниц, некоторые стразу на уровне таблиц.
    Вот наши хинты. Будьте осторожны, не выполняйте эти скрипты "в тупую".

    Код:
    ALTER INDEX ALL ON [dbo].[КРОК$G_L_Entry]		SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$17$0]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$G_L_Correspondence_Entry]	SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$12401$0]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$12401$1]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Ledger_Entry_Dimension]		SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = ON);
    ALTER INDEX ALL ON [dbo].[КРОК$Posted_Document_Dimension]	SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = ON);
    ALTER INDEX ALL ON [dbo].[КРОК$Analysis_View_Entry]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = ON);
    ALTER INDEX ALL ON [dbo].[КРОК$Cust__Ledger_Entry]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$21$0]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Detailed_Cust__Ledg__Entry]	SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$379$0]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Vendor_Ledger_Entry]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$25$0]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Detailed_Vendor_Ledg__Entry]	SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$380$0]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Item_Ledger_Entry]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Item_Application_Entry]		SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$32$0]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Item_Entry_Relation]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$VAT_Entry]		SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Bank_Account_Ledger_Entry]	SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$271$0]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Reservation_Entry]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = ON);
    ALTER INDEX ALL ON [dbo].[КРОК$Item_Application_Entry]		SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Value_Entry]		SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$5802$0]			SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Value_Entry_Relation]		SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$FA_Ledger_Entry]	SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = OFF);
    ALTER INDEX ALL ON [dbo].[КРОК$Sales_Line]		SET (ALLOW_ROW_LOCKS = OFF, ALLOW_PAGE_LOCKS = ON);
  • 3
    Отложенный учет (постановка в очередь, для учета ночью роботом. Перед постановкой - предучетные проверки в режиме READUNCOMMITTED)
  • 4
    Изничтожить SETCURRENTKEY везде где возможно (мало того, что изза него SQL строит кривые планы запросов, так еще и блокировки идут не по ключу).
  • 5
    Своевременно (ежедневно) обновлять статистику по индексам. (Правильные планы запросов=>правильный ключ=>меньше заблокированных строк)
  • 6
    Plan Guides. (Хинты для запросов, позволяют сделать тюнинг особо частых запросов на построение оптимального плана) в BOL написано достаточно подробно.
  • 7
    Поменьше FIND('+'),FIND('-'). Побольше ISEMPTY, FINDFIRST, FINDLAST, FINDSET. (Для примера, проверка наличия записей с помощью ISEMPTY быстрее FIND('-') более чем в 10000 раз).
  • 8
    Поменьше длинных индексов. (Об этом много рассказано на форуме. Делайте индексы по принципу: "Первое поле индекса бьет, второе - добивает").
  • 9
    Поменьше SIFTов (Об этом также неоднократно говорилось)
Возможно чтото было еще, сразу не вспомнишь