AXForum  
Вернуться   AXForum > Microsoft Dynamics NAV > NAV: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.11.2007, 23:24   #1  
ekya is offline
ekya
Участник
 
16 / 10 (1) +
Регистрация: 14.05.2007
Всем привет.

Хотелось бы обсудить преимущества FINDSET над FIND('-').
Уточняю, я рассматриваю FINDSET без параметров.

На сколько я понимаю, FINDSET не создает курсор, что не блокирует набор данных, НО если набор данных превысит максимальный размер записей для кеширования, то курсор все таки будет создан. Т.е. FINDSET дает выигрышь в производительности только до 500 (по умолчанию) записей.

Поправьте меня если я не прав и хотелось бы услышать другие мнения.
Старый 19.08.2009, 17:11   #2  
kgenius is offline
kgenius
Участник
 
98 / 10 (1) +
Регистрация: 27.10.2004
Мне вот показалось, что FINDSET берет информацию блоками по 500 записей по-умолчанию.
Старый 20.08.2009, 12:24   #3  
Alterant is offline
Alterant
Участник
 
378 / 10 (1) +
Регистрация: 31.03.2004
Цитата:
Сообщение от ekya Посмотреть сообщение
Всем привет.

Хотелось бы обсудить преимущества FINDSET над FIND('-').
Уточняю, я рассматриваю FINDSET без параметров.

На сколько я понимаю, FINDSET не создает курсор, что не блокирует набор данных, НО если набор данных превысит максимальный размер записей для кеширования, то курсор все таки будет создан. Т.е. FINDSET дает выигрышь в производительности только до 500 (по умолчанию) записей.

Поправьте меня если я не прав и хотелось бы услышать другие мнения.
Верно, но даже если датасет будет больше 500 записей, то выигрыш в производительности все равно будет, за счет того, что первые 500 записей будут обработаны без использования курсора.
Старый 13.06.2013, 07:38   #4  
smoyk is offline
smoyk
Участник
 
188 / 13 (1) ++
Регистрация: 20.04.2007
В справке не нашел информации о параметрах по умолчанию для FINDSET, не подскажете, с какими она вызывается? Экспериментировать неохото)
Старый 13.06.2013, 10:47   #5  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Цитата:
Сообщение от smoyk Посмотреть сообщение
В справке не нашел информации о параметрах по умолчанию для FINDSET, не подскажете, с какими она вызывается? Экспериментировать неохото)
Цитата:
FINDSET (Record)
Use this function to find a set of records in a table based on the current key and filter. The records can only be retrieved in ascending order.

Ok := Record.FINDSET([ForUpdate][, UpdateKey])
Ok

Data type: boolean

If you omit this optional return value, a run-time error occurs if the system cannot find a record. If you include a return value, the system assumes you will handle any errors. Ok can have these values:

If Ok is...
It means the record set was...

TRUE
Found

FALSE
Not found


Record

Data type: record

If the record was...
Then...

Found
The system returns the record in Record and sets any FlowField in the record to zero. You must update them using CALCFIELDS.

Not found
A run-time error occurs, if you omitted the return value Ok.


ForUpdate

Data type: boolean

Set this to FALSE if you don't intend to modify any records in the set.

Set this to TRUE if you want to modify some records in the set.

If you set this parameter to TRUE, a LOCKTABLE is immediately performed on the table before the records are read.

UpdateKey

Data type: boolean

This only applies if ForUpdate is set to TRUE.

If you are going to modify any field value within the current key, set this parameter to TRUE.

Comments
You should only use this function when you explicitly want to loop through a recordset. You should ONLY use this function in combination with REPEAT .. UNTIL.

Furthermore, FINDSET only supports descending loops. If you want to loop from the bottom up, you should use FIND(‘+’).

The general rules for using FINDSET are:

• FINDSET(FALSE,FALSE)- read-only. This uses no server cursors and the record set is read with a single server call.

• FINDSET(TRUE,FALSE)- is used to update non-key fields. This uses a cursor with a fetch buffer similar to FIND(‘-’).

• FINDSET(TRUE,TRUE)- is used to update key fields.

Note
This function is designed to optimize finding and updating sets. If you set any or both of the parameters to FALSE, you can still modify the records in the set but these updates will not be performed optimally.

Example
The following C/AL code examples show how to use the FINDSET function:

Example 1

// Looping through a set without updating it.

SalesLine.SETFILTER("Purch. Order Line No.",'<>0');

IF SalesLine.FINDSET THEN BEGIN

REPEAT

CopyLine(SalesLine);

UNTIL SalesLine.NEXT = 0;

END;



Example 2

// Looping through a set and updating a field that is not within the current key.

SalesLine.SETRANGE("Document Type",DocumentType);

SalesLine.SETRANGE("Document No.",DocumentNo);

IF SalesLine.FINDSET(TRUE, FALSE) THEN BEGIN

REPEAT

SalesLine."Location Code" := GetNewLocation(SalesLine);

SalesLine.MODIFY;

UNTIL SalesLine.NEXT = 0;

END;



Example 3

// Looping through a set and updating a field that is within the current key.

SalesShptLine.SETRANGE("Order No.",SalesLine."Document No.");

SalesShptLine.SETRANGE("Order Line No.",SalesLine."Line No.");

SalesShptLine.SETCURRENTKEY("Order No.","Order Line No.");

IF SalesShptLine.FINDSET(TRUE, TRUE) THEN BEGIN

REPEAT

SalesShptLine."Order Line No." := SalesShptLine."Order Line No." + 10000;

SalesShptLine.MODIFY;

UNTIL SalesShptLine.NEXT = 0;

END;

Старый 13.06.2013, 11:04   #6  
artkashin is offline
artkashin
Участник
MCBMSS
 
519 / 18 (2) ++
Регистрация: 06.12.2006
Господа не все так однозначно))) Вот например, выдержка из хелпа по 2009 наву (выделенное жирным заставляет меня задумываться о возвращении использования FIND('-'), но все надо тестировать, а руки не доходят):
The FINDSET operation optimizes reading records from SQL Server by establishing a stream of records between Microsoft Dynamics NAV and SQL Server. While the stream is open, no other activity occurs between Microsoft Dynamics NAV and SQL Server. Before the records are read, Microsoft Dynamics NAV has no information about how many records are available to read. However, Microsoft Dynamics NAV must allocate enough memory to accommodate all records that it will read for the FINDSET operation. The stream does not allow it to read records in groups. Microsoft Dynamics NAV allocates memory for a preset number of records and then begins reading the records. You can change the value of this preset number by changing the Record Set value in the New Database or Alter Database window. For more information, see the topic "Entering Information in the New Database - Advanced Tab" in the Microsoft Dynamics NAV Application Help.
Note
In Microsoft Dynamics NAV 2009, the default value is 50. In Microsoft Dynamics NAV 5.0, when the FINDSET operation was introduced, the default value was 500.

If the number of records that is read falls within this range, then all records are read with optimized performance. If there are more records to read than the preset number, then Microsoft Dynamics NAV must establish new commands to SQL Server to continue reading records. Microsoft Dynamics NAV reads all records successfully, but the additional commands are expensive for SQL Server to execute. The FIND('-') operation is more efficient than the FINDSET operation when there are more records to read than the preset number.

Note
If Microsoft Dynamics NAV detects a pattern in which FINDSET would be a better choice than FIND, then it converts the FIND operation to a FINDSET operation.
Старый 18.06.2013, 12:17   #7  
Captain is offline
Captain
Участник
Лучший по профессии 2017
 
300 / 81 (3) ++++
Регистрация: 28.02.2003
Здесь все расписано от Waldo

What impact does my C/AL have on SQL?
__________________
---------------------------------------------------------------------------------------------
"Собрать стадо из баранов легко, трудно собрать стадо из кошек" Профессор Сергей Капица
Старый 24.06.2013, 10:57   #8  
smoyk is offline
smoyk
Участник
 
188 / 13 (1) ++
Регистрация: 20.04.2007
Спасибо Kadawrik за цитирование справки из своего навика, у меня примерно такая же, но т.к. есть отличия, мне пришлось перечитать ее еще раз... Вопрос актуален, с какими параметрами по умолчания вызывается FINDSET? Мне не по глазам или просто с первого раза был непонятен мой вопрос?) Я так и не нашел этого...
Старый 24.06.2013, 17:00   #9  
Kadawrik is offline
Kadawrik
Участник
 
279 / 11 (1) +
Регистрация: 04.11.2010
Цитата:
Сообщение от smoyk Посмотреть сообщение
с какими параметрами по умолчания вызывается FINDSET?
Если верить приведенной выше справке, то вызов FINDSET без параметров = FINDSET(FALSE,FALSE)
Старый 01.07.2013, 01:00   #10  
RedFox is offline
RedFox
Участник
 
1,441 / 10 (0) +
Регистрация: 28.12.2004
Адрес: Киев
Цитата:
Сообщение от Kadawrik Посмотреть сообщение
Если верить приведенной выше справке, то вызов FINDSET без параметров = FINDSET(FALSE,FALSE) />
Не советовал бы я верить этим справкам.. Почитайте лучше то, что написали в "What impact does my C/AL have on SQL?"
Старый 19.06.2014, 10:43   #11  
zuzka is offline
zuzka
Участник
Аватар для zuzka
 
131 / 10 (1) +
Регистрация: 29.07.2013
В развитии своей проблемы забрел в эту тему)) Собственно профайлер SQL показал:

1. При FINDSET в SQL при обходе в цикле происходит следующее(запрос целиком не привожу - ясно будет и так, в конце каждого запроса имеется WHERE по наложенным на таблицу фильтрам):
SELECT TOP 51 ......... - при первом подходе и
SELECT TOP 1 ........ до конца выборки, если в ней больше выбранных за первый подход записей

2. При FIND('-') выявлено:
SELECT (*) .......

Итог:
Если в таблице после наложения фильтров остается 1-150 записей - FINDSET работает быстрее FIND('-'), причем увеличение записей приводит к их уравниванию.
Примерно одинаково отрабатывают оба варианта в диапазоне 200-400 записей
Если выборка составляет более 1000 записей FIND('-') выигрывает у FINDSET уже довольно серьезно (на 36000 записей: FINDSET показал результат 258000мс, FIND('-') - 150000мс. Был организован простой проход в цикле по записям выборки с записью в лог разницы во времени между итерациями цикла, таблица "Customer Ledger Entry").

Пост всего лишь описание найденного узкого места по FIND vs FINDSET - необходимо представлять какое количество будет при выборке, и в зависимости от этого плясать...
__________________
Как только вы проиграете, все ваши прошлые победы забудут.
Старый 14.07.2014, 13:34   #12  
Storkich is offline
Storkich
Участник
 
149 / 10 (1) +
Регистрация: 08.03.2007
Уже что-то не так в логике, раз приходится переперать сотни записей.
Есть ещё косяк интересный, если рекурсивно делать FINDSET к одной и той же таблице(вложенно).
FINDSET вроде как кеширует набор, но при вложенности кеш слетает, и летят кривые запросы к базе. Жуть как торомозит.
Старый 30.09.2015, 12:36   #13  
Predatore is offline
Predatore
Участник
 
163 / 17 (1) ++
Регистрация: 29.09.2010
Нашёл сегодня повод поднять эту старую тему.
Я тут случайно обнаружил, что из NAV2013 и NAV2015 исчез параметр отвечающий за размер кэша для FINDSET. Кроме того, из хелпа пропали описания различий между FIND и FINDSET. Сами же описания данных функций стали до безобразия скудны.
Всё это заставляет задуматься, а как теперь всё это работает? И где про это можно почитать?
 

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 09:31.