|
|
|
|
#1 |
|
Участник
|
Цитата:
При нормальных ключах и статистике ключ выбирается правильно, даже если не указан setcurrentkey, т.е. только с условием where.
Цитата:
Сообщение от ;362029
Можно привести массу примеров, где это утверждение не верно.
|
|
|
|
|
#2 |
|
Участник
|
Цитата:
Цитата:
Сообщение от smoyk
Естественно, но так как мы сортируем именно по полям, по которым проводим поиск, то никакие другие примеры здесь не уместны Вызывая SETCURRENTKEY мы не только сортируем (что значительно ускоряет поиск), но и явно указываем выбираемый ключ. Если SQL 2005 выберет другой ключ исходя из своей логики, думаю это будет не правильно. Думаю, он этого и не сделает имхо. Или я не прав и Вы можете такие примеры привести?
|
|
|
|
|
#3 |
|
Участник
|
Цитата:
Сообщение от MSI
И для каждого из таких запросов, как я понял, надо приципить свой план. Геморройно... Или надо что-то не так делать? Может мы не так лечим и надо действительно сделать обновление статистики и сиквель должен начать правильно выстраивать планы выполнения? Или можно как-то назначить план на группу запросов?
К сожалению, обновление статистики сможет починить лишь запросы, которые идут из кода. (Тем не менее обновлять статистику нужно обязательно. По особо большим и популярным таблицам - каждую ночь) При открытии же форм, как раз идут запросы с > >= < и <=. Например при фильтрации финансовых операций по счету будет запрос: Код: 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Очевидно, что если в качестве @P2 первый раз было передано большое число, то план будет построен по кластерному индексу. (Если @P2 маленькое, то план будет правильный - состоять из джоина Index Seek по G_L_Account и Clustered Index Seek) И в дальнейшем, этот план по кластерному индексу будет использован и для маленьких @P2, что будет приводить к сканированию всей таблицы. Эти случаи надо фиксить Plan Guide'ами |
|
|
|
|
#4 |
|
Участник
|
Цитата:
Во первых набор данных будет упорядочен по первичному ключу. В вторых, поиск будет идти быстрее, поскольку при использовании не кластерного индекса, к нему всегда идет join кластерного, в котором данные как раз УЖЕ упорядочены по первичному ключу. Цитата:
Это дополнительное действие, которое либо является отдельным пунктом плана запроса, либо входит в этап джоина таблиц. Пример будет вечером. Специально сделаю его на CRONUS, чтобы Вам удалось его повторить. |
|
|
|
|
#5 |
|
Участник
|
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('-');Код: 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'
|
|
|