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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.10.2007, 05:45   #1  
smoyk is offline
smoyk
Участник
 
188 / 13 (1) ++
Регистрация: 20.04.2007
Цитата:
При нормальных ключах и статистике ключ выбирается правильно, даже если не указан setcurrentkey, т.е. только с условием where.
Ну возможно, но в этом случай поиск будет идти много медленее, т.к. набор данных не будет упорядочен. Поэтому думаю, что даже в этом случае вызов SETCURRENTKEY будет оправдан.
Цитата:
Сообщение от ;362029
Можно привести массу примеров, где это утверждение не верно.
Естественно, но так как мы сортируем именно по полям, по которым проводим поиск, то никакие другие примеры здесь не уместны Вызывая SETCURRENTKEY мы не только сортируем (что значительно ускоряет поиск), но и явно указываем выбираемый ключ. Если SQL 2005 выберет другой ключ исходя из своей логики, думаю это будет не правильно. Думаю, он этого и не сделает имхо. Или я не прав и Вы можете такие примеры привести?
Старый 19.10.2007, 13:08   #2  
MSI is offline
MSI
Участник
 
25 / 10 (1) +
Регистрация: 03.10.2006
Цитата:
Сообщение от smoyk Посмотреть сообщение
Ну возможно, но в этом случай поиск будет идти много медленее, т.к. набор данных не будет упорядочен. Поэтому думаю, что даже в этом случае вызов SETCURRENTKEY будет оправдан.
То что Вы указываете SETCURRENTKEY заставляет сиквель лишь упорядочить то, что получится в результате выполнения запроса. Сама выборка будет выполнятся в соответствии с планом запроса, составленного сиквелем когда-то ранее. План сиквель выбирает сам.

Цитата:
Сообщение от smoyk Посмотреть сообщение
Естественно, но так как мы сортируем именно по полям, по которым проводим поиск, то никакие другие примеры здесь не уместны Вызывая SETCURRENTKEY мы не только сортируем (что значительно ускоряет поиск), но и явно указываем выбираемый ключ. Если SQL 2005 выберет другой ключ исходя из своей логики, думаю это будет не правильно. Думаю, он этого и не сделает имхо. Или я не прав и Вы можете такие примеры привести?
Наблюдаю массу примеров. Ставлю ключ по таблице - сиквель начинает выполнять Clustered Index Seek. Убираю - вот вам Индексный поиск. Ситуация имеет тенденцию самопроизвольно меняться до наоборот . С ключом Index Seek. Без ключа Clustered Index Seek (логично). Замучившись окончательно понять логику стали прицеплять принудительно планы выполнения к каждому из запросов. Утомительная задачка вышла, однако. На казалось бы одну и ту же примитивную конструкцию в C\AL коде сиквель генерит довольно много разных вариаций одного и того же запроса ( иногда отличающихся лишь одним знаком - напр '<' вместо '<='). И для каждого из таких запросов, как я понял, надо приципить свой план. Геморройно... Или надо что-то не так делать? Может мы не так лечим и надо действительно сделать обновление статистики и сиквель должен начать правильно выстраивать планы выполнения? Или можно как-то назначить план на группу запросов?
Старый 19.10.2007, 14:00   #3  
Голышев Михаил is offline
Голышев Михаил
Участник
 
106 / 10 (1) +
Регистрация: 03.07.2006
Цитата:
Сообщение от MSI Посмотреть сообщение
И для каждого из таких запросов, как я понял, надо приципить свой план. Геморройно... Или надо что-то не так делать? Может мы не так лечим и надо действительно сделать обновление статистики и сиквель должен начать правильно выстраивать планы выполнения? Или можно как-то назначить план на группу запросов?
Если вы испльзуете Plan Guide - то для каждого запроса свой хинт. (у нас их около 500 на одну БД)

К сожалению, обновление статистики сможет починить лишь запросы, которые идут из кода.
(Тем не менее обновлять статистику нужно обязательно. По особо большим и популярным таблицам - каждую ночь)

При открытии же форм, как раз идут запросы с > >= < и <=.
Например при фильтрации финансовых операций по счету будет запрос:
Код:
exec sp_executesql N'SELECT  * FROM "dbo"."КРОК$G_L_Entry" WHERE (("G_L_Account_No_"=@P1)) 
AND  "Entry_No_">=@P2 ORDER BY "Entry_No_" OPTION (FAST 10)',
N'@P1 varchar(20),@P2 int','61100100',4
При этом план строится 1 раз, компилируется и будет использован для параметризированного запроса при любых параметрах.

Очевидно, что если в качестве @P2 первый раз было передано большое число, то план будет построен по кластерному индексу. (Если @P2 маленькое, то план будет правильный - состоять из джоина Index Seek по G_L_Account и Clustered Index Seek)
И в дальнейшем, этот план по кластерному индексу будет использован и для маленьких @P2, что будет приводить к сканированию всей таблицы.

Эти случаи надо фиксить Plan Guide'ами
Старый 19.10.2007, 13:42   #4  
Голышев Михаил is offline
Голышев Михаил
Участник
 
106 / 10 (1) +
Регистрация: 03.07.2006
Цитата:
Сообщение от smoyk Посмотреть сообщение
Ну возможно, но в этом случай поиск будет идти много медленее, т.к. набор данных не будет упорядочен.
Простите, но это бред.
Во первых набор данных будет упорядочен по первичному ключу.
В вторых, поиск будет идти быстрее, поскольку при использовании не кластерного индекса, к нему всегда идет join
кластерного, в котором данные как раз УЖЕ упорядочены по первичному ключу.
Цитата:
Сообщение от smoyk Посмотреть сообщение
Вызывая SETCURRENTKEY мы не только сортируем (что значительно ускоряет поиск)
Каким образом сортировка УСКОРЯЕТ поиск?!
Это дополнительное действие, которое либо является отдельным пунктом плана запроса, либо входит в этап джоина таблиц.
Цитата:
Сообщение от smoyk Посмотреть сообщение
но и явно указываем выбираемый ключ. Если SQL 2005 выберет другой ключ исходя из своей логики, думаю это будет не правильно. Думаю, он этого и не сделает имхо. Или я не прав и Вы можете такие примеры привести?
Пример будет вечером. Специально сделаю его на CRONUS, чтобы Вам удалось его повторить.
Старый 19.10.2007, 22:23   #5  
Голышев Михаил is offline
Голышев Михаил
Участник
 
106 / 10 (1) +
Регистрация: 03.07.2006
Цитата:
Сообщение от smoyk Посмотреть сообщение
Или я не прав и Вы можете такие примеры привести?
CRONUS Россия ЗАО (navision sp3) на ms sql 2005
Типичный пример на 17 таблице.

Прежде всего, заполняем фин книгу (300 записей - это не серьезно)

Код:
Name	DataType	Subtype	Length
i	Integer		
dlg	Dialog		
recGenJnlTEMP	Record	Gen. Journal Line	
recGenJnlDimTEMP	Record	Journal Line Dimension	
Gen. Jnl.-Post Line	Codeunit	Gen. Jnl.-Post Line	
---------
dlg.OPEN('@1##################');
FOR i := 1 TO 1000000 DO BEGIN
  dlg.UPDATE(1,i DIV 100);
  recGenJnlTEMP.DELETEALL;
  recGenJnlTEMP.INIT;
  recGenJnlTEMP.VALIDATE("Posting Date" , 010105D);
  recGenJnlTEMP.VALIDATE("Account Type" , recGenJnlTEMP."Account Type"::Customer);
  recGenJnlTEMP.VALIDATE("Account No." , '49633663');
  recGenJnlTEMP.VALIDATE("Document No." , 'INITIAL');
  recGenJnlTEMP.VALIDATE(Description , 'Автозапонение');
  recGenJnlTEMP.VALIDATE(Amount,100);
  recGenJnlTEMP.VALIDATE("Bal. Account Type",recGenJnlTEMP."Bal. Account Type"::"G/L Account");
  recGenJnlTEMP.VALIDATE("Bal. Account No.",'68-800');
  recGenJnlTEMP.VALIDATE("Shortcut Dimension 1 Code",'ПРОДАЖИ');
  recGenJnlTEMP.VALIDATE("Shortcut Dimension 2 Code",'МЕРСЕДЕС');
  recGenJnlTEMP.INSERT;
  recGenJnlDimTEMP.DELETEALL;
  recGenJnlDimTEMP.INIT;
  recGenJnlDimTEMP."Table ID" := 81;
  recGenJnlDimTEMP."Dimension Code" := 'ПРОДМЕНЕД';
  recGenJnlDimTEMP."Dimension Value Code" := 'ВК';
  recGenJnlDimTEMP.INSERT;
  "Gen. Jnl.-Post Line".RunWithCheck(recGenJnlTEMP,recGenJnlDimTEMP);
  COMMIT;
END;
Обновляем статистику, перестраиваем индексы и выполняем запрос:
Код:
recGLEntry.RESET;
recGLEntry.SETCURRENTKEY("Source Type","Source No.");
recGLEntry.SETRANGE("Source Type",recGLEntry."Source Type"::Customer);
recGLEntry.SETRANGE("Source No.",'49633663');
recGLEntry.SETRANGE("Document No.",'104005');
recGLEntry.FIND('-');
Код SQL при этом:
Код:
exec sp_executesql 
N'SELECT  * FROM "CRONUS"."dbo"."CRONUS Россия ЗАО$G_L Entry" WITH (READUNCOMMITTED)   WHERE (("Source Type"=@P1)) AND (("Source No_"=@P2)) AND (("Document No_"=@P3)) ORDER BY "Source Type","Source No_","G_L Account No_","Global Dimension 1 Code","Global Dimension 2 Code","Business Unit Code","Posting Date","Entry No_" OPTION (FAST 5)',
N'@P1 int,@P2 varchar(20),@P3 varchar(20)'
,1,'49633663','104005'
План запроса:
 

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

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

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

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

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