28.12.2004, 11:09 | #1 |
Участник
|
Здравствуйте, Подскажите какую запись вернет FIND('=><') ???
|
|
28.12.2004, 12:01 | #2 |
Заноза в заднице
|
Тут может быть два варианта: либо все записи, либо вообще ничего. Все записи будут возвращены в случае, если до вызова FIND определены значения полей текущего (CURRENTKEY) и первичного (PRIMARY) ключей. В противном случае FIND ничего не возвратит.
__________________
Лень мудрого человека - это необходимое средство нейтрализации кипучей активности руководящих им дураков! |
|
28.12.2004, 12:04 | #3 |
Moderator
|
FIND вернет не запись, а значение TRUE.
А уж что вернет переменная типа Record это науке не известно |
|
28.12.2004, 12:13 | #4 |
Заноза в заднице
|
Цитата:
Сообщение от tyrex
FIND вернет не запись, а значение TRUE.
А уж что вернет переменная типа Record это науке не известно Если FIND возвратит значение TRUE, тогда это означает, что в записи, либо ссылке на запись, к которой применён FIND, отобраны все существующие строки. Если же FIND возвратил FALSE, то это значит, что в записи, к которой применялся отбор "не всё в порядке" (смотри выше), и, соответственно, ни одной строки не будет включено в отбор.
__________________
Лень мудрого человека - это необходимое средство нейтрализации кипучей активности руководящих им дураков! |
|
28.12.2004, 12:40 | #5 |
Участник
|
Спасибо большое за ответ!
|
|
28.12.2004, 13:18 | #6 |
Moderator
|
Обычно конструкцию IF "Что-то-там".FIND('=><') THEN ... применяют для проверки отфильтрованной таблицы на наличие записей
|
|
28.12.2004, 14:22 | #7 |
Участник
|
хм... функция действительно возвращает булево значение, но думаю, вопрос был не об этом...
Вообще говоря, параметр функции Find указывает, на какой позиции в наборе данных следует установить курсор. Чаще всего в коде используют '-' (первая) или '+' (последняя запись). Конструкция ('=><') означает "спозиционироваться на текущую запись, а при её отсутствии в наборе данных - на следующую ближайшую запись к ней" (в соответствии со значениями ключевых полей записи и установленным порядком сортировки). Навижен неявно использует её, например, при открытии формы, свойство которой "SourceTablePlacement" установлено в <Saved> (значение по умолчанию). Легко догадаться что ('=<>') - спозиционироваться на текущую или предыдущую запись. PS. напомню, что "текущую запись" определяют значения полей, входящих в ключ, выбранный в этот момент для сортировки таблицы. Таким образом, подобную конструкцию в коде удобно использовать, когда известны не все значения "ключевых полей" (в кавычках потому что это не обязательно поля первичного ключа, в навижене все индексы ключами называют...) |
|
29.12.2004, 06:43 | #8 |
Участник
|
Большое спасибо Wizard за такой полный, подробный и понятный ответ.
|
|
29.12.2004, 09:35 | #9 |
Участник
|
Greggy, форум позволяет добавить респект тем участникам, ответы которых вам понравились.
Для того, чтобы добавить респект нажмите + в строке Респекты слева от сообщения. |
|
29.12.2004, 09:58 | #10 |
Участник
|
Да не за что... Замечу всё таки, что все параметры этой функции в справке описаны, не сказано только что их можно комбинировать, перечисляя в порядке приоритета...
Но я не об этом, вот о чем: Цитата:
Обычно конструкцию IF "Что-то-там".FIND('=><') THEN ... применяют для проверки отфильтрованной таблицы на наличие записей
Не рекомендую использовать ни FIND, ни ISEMPTY для проверки фильтрованного набора данных на наличие в нём записей. Возьмусь в данном случае поспорить со справкой - опыт показывает что COUNT с проверкой на 0 отрабатывает значительно быстрее. Попробую пояснить почему: Навижен, при обращении к записям таблицы, всегда запрашивает у SQL сервера "звездочки" (SELECT * FROM...). В результате даже при наличии подходящего SQL индекса сервер вынужден вычитывать страницы с данными. В случае же использования COUNT серверу достаточно индекса для подсчета записей. Конечно, вопрос производительности сложный и надо к любым советам относиться с осторожностью, но опыт... |
|
29.12.2004, 12:59 | #11 |
Moderator
|
Не согласен.
операции типа MyTable.FIND генерируют запрос вида Код: SELECT * FROM MyTable WHERE "Key"=@P1 Код: SELECT COUNT(*) FROM MyTable WHERE "Key"=@P1 Поэтому правильнее использовать FIND |
|
29.12.2004, 16:01 | #12 |
Участник
|
ваше право...
однако мне не знакомо определение, по которому это не может работать быстрее, а вот почему реально работает быстрее - я написал. Предлагаю сомневающимся ставить эксперименты самостоятельно. Ещё раз подчеркну - важно наличие подходящих SQL индексов. |
|
29.12.2004, 16:32 | #13 |
Moderator
|
Я не сомневаюсь, я утверждаю.
Специально поставил эксперимент на кронусе. Выставил аудит на сиквеле. Создал таблицу в 10 млн записей. Написал два простейших кода в стиле SETFILTER - FIND, SETFILTER - COUNT. Запустил профайлер для каждого и замерил время. Если есть желающие посмотреть, какие в действительности SQL-запросы генерирует навижн - пишите - опубликую |
|
29.12.2004, 17:51 | #14 |
Участник
|
Цитата:
Сообщение от tyrex
Если есть желающие посмотреть, какие в действительности SQL-запросы генерирует навижн - пишите - опубликую
А может лучше статью? В стиле http://axapta.mazzy.ru/hints/indexhints/ и http://axapta.mazzy.ru/hints/indexhi...leresults.html |
|
29.12.2004, 18:07 | #15 |
Участник
|
Спасибо, коллега tyrex, что не забросили тему, надеюсь с вашей помощью всё таки довести до аудитории суть своих рекомендаций.
Во-первых вспомним, что речь шла о проверке набора данных на наличие в нем записей... Вопрос: а зачем это вообще делать? - вопрос открытый. На мой взгляд - для того, чтобы принять решение о продолжении обработки этого набора данных. А почему бы сразу не открыть для этого курсор, как обычно IF FIND('-') THEN REPEAT ... UNTIL NEXT=0; если вероятность того, что записей не окажется, маленькая (что обычно бывает) - то дополнительной проверки на пустоту не нужно делать, поскольку всё равно для заполнения табличной переменной реальными значениями FIND придется вызвать. А вот если вероятность от FIND('-') получить FALSE достаточно велика - дополнительная проверка становится осмысленной. Для того, чтобы получить описанный мной эффект надо построить подходящий SQL индекс, в который бы входили все поля, участвующие в фильтре. Конечно, важно чтобы этот индекс был достаточно селективным. Так вот, для того чтобы обработать запрос <SELECT COUNT(*) FROM MyTable WHERE "Key"=@P1> серверу в этом случае не придется обращаться к данным в таблице, и выигрыш во времени получится существенным. В моем опыте конструкция IF COUNT <> 0 THEN BEGIN FIND('-'); REPEAT ... UNTIL NEXT=0; END; привела к ускорению соответствующего процесса в разы. Замечу для точности что сам этот кусок кода находился в цикле обработки другого, основного набора данных, на основании которого определялись значения фильров. Получив такой результат, я прошелся по тем местам кода, где вспомнилась именно проверка "на пустоту", когда потребности в самих данных нет. Во всех случаях замена на COUNT привела к ускорению процессов. Именно это и позволило мне выдать такие рекомендации. |
|
30.12.2004, 14:45 | #16 |
Участник
|
Благо перед праздниками удалось выкроить свободного времени, провел ревизию своего утверждения про функцию ISEMPTY.
При её вызове Навижен генерит запрос вида Код: SELECT TOP 1 NULL FROM TABLE WHERE FIELD1=@P1 Код: SELECT TOP 1 * FROM TABLE WHERE FIELD1=@P1 ORDER BY <CURRENTKEY FIELDS> select TOP 1 NULL свободен от этих недостатков, и в смысле использования индексов работает аналогично COUNT, но, конечно, ограничивается первой попавшейся записью в индексе и концептуально лучше. К своему сожалению я не могу сейчас повторить ситуацию, в которой на моей базе COUNT был лучше чем ISEMPTY, поэтому: 1. Снимаю свои призывы использовать COUNT 2. Оставляю в силе рекомендацию не использовать FIND 3. Предлагаю использовать ISEMPTY 4. На мой взгляд проводить эксперименты с производительностью лучше не на тестовых примерах а на собственных данных, от их организации и наполнения многое зависит. 5. Посыпать голову пеплом пока не буду, поскольку было такое... ("у меня все ходы записаны" (С), профайлер запускался и результаты запротоколированы, ошибки не было). Повторится ситуация - отпишу обязательно. Модератору: на мой взгляд, обсуждение использования COUNT лучше вынести в отдельную тему форума, начиная с моей фразы "Но я не об этом, вот о чем:" PS. tyrex'у - респект за неравнодушное отношение. |
|
04.01.2005, 13:55 | #17 |
Участник
|
Народ, а как Вы отслеживаете генерацию sql-левских селектов от кода в навижен?
Используете ли Вы встроенные средства в навижине для мониторинга производительности? |
|
04.01.2005, 14:02 | #18 |
Участник
|
Да и респект wizardу за грамотные советы в отношении скорости обработки комманд find, isempty, count.
|
|
26.01.2005, 15:42 | #19 |
Участник
|
The number of filters that you have applied to the records affects the speed of the ISEMPTY function. The fewer the number of filters, the faster the system performs the operation.
When you are using SQL Server, this function is faster than using the Record.COUNT function and then testing the result for zero. RTFM |
|