Показать сообщение отдельно
Старый 01.10.2007, 16:14   #25  
Голышев Михаил is offline
Голышев Михаил
Участник
 
106 / 10 (1) +
Регистрация: 03.07.2006
Цитата:
Сообщение от Critic Посмотреть сообщение
1) golyshev, а вы с какой версией навика работаете? Роботают ли ваши рекомендации для версии 3.60 (3.70А) ?
2) судя по
Код:
recCustLedgerEntry.RESET;
recCustLedgerEntry.SETRANGE("External Document No.",'SCI_604983/SZ622586');
recCustLedgerEntry.SETRANGE("Posting Date",200906D);
recCustLedgerEntry.SETRANGE("Customer No.",'C3137');
recCustLedgerEntry.FIND('-');
и
Код:
SELECT  * FROM "dbo"."КРОК$Cust__Ledger_Entry" 
WHERE (("External_Document_No_"='03')) 
  AND (("Customer_No_"='C3438')) 
  AND (("Posting_Date"='2006-11-23')) 
ORDER BY "Entry_No_"
SQLю вообще ровно на положение SETRANGE в коде навика или все-таки этим можно повлиять на ускорение обработки?
1) Мы работаем в 4.0, но это верно для 3.6 и 3.7
2) не понял суть вопроса. SETRANGE - это поле WHERE в SQL запросе, SETCURRENTKEY - это поле ORDER by в SQL запросе.

Цитата:
Сообщение от MSI Посмотреть сообщение
Честно говоря, наблюдал массу вещей под сиквелем, кот. слабо укладываются в понимание. Например, что списочная форма, отображающая отфильтрованную большую таблицу с установленным ключом, отличным от первичного невероятно тупит при навигации. Стоит для уже отвильтрованного рекордсета выставить первичный ключ - работа формы становится много быстрее. Насчет выставления ключа тоже не все столь однозначно: есть пример отчетов, которые работает по разному в зависимости от выставленного ключа, причем с ключом они работают значительно быстрее, чем без него. Это немного неукладывается со сказанным в посте выше. Прихожу к выводу, что по наву под сиквелем все очень не однозначно, и на постоянно возникающие вопросы никакие SQL troubleshooting referencы не дают ответов....
Безусловно, убирать SETCURRENTKEY в местах, где он влияет на бизнес-логику нельзя
(например кодеюнит коррекции себестоимости. Чтобы его ускорить и отказаться от SETCURRENTKEY мы его сильно переписали)

Конечно, есть ситуации, когда указание ключа ускоряет запрос. Каждый случай надо рассматривать индивидуально.

Но если понять почему происходит ускорение, то зачастую становится ясно, что быстрее всё равно будет с сортировкой по первичному ключу. Надо лишь подточить запрос.

Чаще всего это касается списочных форм на большой таблице.

Вот пример:
Форма на 17 таблице (Фин Журнал) с наложенными фильтрами по Posting Date, G/L Account No.,Debit Amount
Сортировка по первичному ключу - Entry No.

Предположим, Вы первый раз открыли форму, navision при этом открывает курсор, следующим запросом:

Код:
SELECT  * FROM "dbo"."КРОК$G_L_Entry" WITH (READUNCOMMITTED)  WHERE (("Posting_Date"=@P1)) AND (("Debit_Amount"<>@P2)) AND (("G_L_Account_No_"=@P3)) AND  "Entry_No_">=@P4 ORDER BY "Entry_No_" OPTION (FAST 5)
План запроса, который будет использован в данном случае сильно зависит от конкретного параметра, переданного в @P4.

Предположим, что @P4 большое число - т.е. форма позиционируется на последних записях.
При этом план запроса будет наверняка Clustered index Seek - т.е. поиск по первичному ключу.

План запроса при этом кешируется, и будет использован для всех запросов, независимо от переданных параметров.
Таким образом, в следующий раз, когда мы откроем форму, и спозиционируемся на первых записях, согласно уже скомпилированному плану, выборка будет идти по кластерному индексу. А так как @P4 у нас маленькое число, то SQL Server просканирует практически всю таблицу.

Если же на форме установить сортировку по Posting Date, то запрос будет
Код:
SELECT  * FROM "croc_na"."dbo"."КРОК$G_L_Entry" WITH (READUNCOMMITTED)  WHERE (("Posting_Date"=@P1)) AND (("Debit_Amount"<>@P2)) AND (("G_L_Account_No_"=@P3)) AND  "Posting_Date"=@P4 AND "Entry_No_">=@P5 ORDER BY "Posting_Date","Entry_No_" OPTION (FAST 5)
SQL server при этом, чтобы скомпенсировать затраты на сортировку, скорее всего выберет ключ G_L_Account_No_,Posting_Date.
И запрос будет выполняться одинакого быстро как для больших @P5 так и для маленьких.


То есть указание порядка сортировки, косвенно влияет на план запроса.
Но скорость отображения формы можно ускорить, если подсказать SQL Server'у что мы от него хотим.

Если создать plan guid для первого запроса, запретив SQL Server'у делать Clutered Index Seek, план построится таким образом, что скорость запроса будет относительно независима от параметров и быстрее второго случая (т.к. в нем будет отсутсвовать сортировка). Скорее всего это будет выборка по ключу G_L_Account_No_,Posting_Date с джоином выборки по кластерному индексу и без сортировки.

Код:
sp_create_plan_guide 
@name =  N'PlanGuid1',
@stmt = 
N'SELECT  * FROM "dbo"."КРОК$G_L_Entry" WITH (READUNCOMMITTED)  WHERE (("Posting_Date"=@P1)) AND (("Debit_Amount"<>@P2)) AND (("G_L_Account_No_"=@P3)) AND  "Entry_No_">=@P4 ORDER BY "Entry_No_" OPTION (FAST 5)',
@type = N'SQL',
@module_or_batch = NULL,
@params = N'@P1 datetime,@P2 decimal(38,20),@P3 varchar(20),@P4 int',
@hints = N'OPTION (OPTIMIZE FOR (@P4 = 0))'
Повторюсь - каждый случай индивидуален