Имя: Пароль:
IT
 
Помогите соптимизировать запрос
0 organizm
 
09.01.13
15:42
Нужно выбрать спецификации где по есть требуемая продукция и материал. Продукция и материал отбираются по коду. Сделал такой запрос: ВЫБРАТЬ
   Спец.Ссылка КАК Спец,
   Вых.Номенклатура КАК Продукция,
   Вх.Номенклатура КАК Материал
ИЗ
   Справочник.СпецификацииНоменклатуры КАК Спец
       ЛЕВОЕ СОЕДИНЕНИЕ Справочник.СпецификацииНоменклатуры.ВыходныеИзделия КАК Вых
       ПО (Вых.Ссылка = Спец.Ссылка)
           И (Вых.НомерСтроки = 1)
       ЛЕВОЕ СОЕДИНЕНИЕ Справочник.СпецификацииНоменклатуры.ИсходныеКомплектующие КАК Вх
       ПО Спец.Ссылка = Вх.Ссылка
ГДЕ
   Вх.Номенклатура.Код = &КодНом
   И Вых.Номенклатура.Код = &КодПрод

работает подозрительно медленно. Посоветуйте что не так?
1 ДенисЧ
 
09.01.13
15:43
добавь индексы.
Ищи не по коду, а по ссылке.
2 organizm
 
09.01.13
15:43
строк таблицы "ИсходныеКомплектующие" что-то около 600 тыс.
3 organizm
 
09.01.13
15:44
по ссылке не подходит, так как искать приходится из внешних данных, т.е. по коду
4 tdm
 
09.01.13
15:45
(3) условие же на равно а не на подобно, т.е. в установке параметров запроса проще ссылку получить
5 organizm
 
09.01.13
15:45
тупит как раз на таблице "ИсходныеКомплектующие"
6 acsent
 
09.01.13
15:45
найди ссылку по коду отдельным запросом
7 tdm
 
09.01.13
15:46
ну и условия из раздела ГДЕ в связи двух таблиц наложить лучше)
8 acsent
 
09.01.13
15:46
добавь индекс по номенклатуре
9 organizm
 
09.01.13
15:47
(7) пробовал, не почувствовал разницы
10 tdm
 
09.01.13
15:47
(8) +1
11 Lexusss
 
09.01.13
15:51
sql + индекс по номенклатуре + переделать на внутреннее соединение.
Подробнее надо смотреть наполненность и статистику таблицы, а так же планы выполнения. Весьма похоже, что SQL сначала сращивает таблицы, а только затем накладывает условия.
12 MrStomak
 
09.01.13
15:52
основная проблема - отсечение записей после запросы. Надо писать условия по коду в условиях соединения. А для использования индекса по номенклатуре, нужно использовать временные таблицы.
что-то вроде
Выбрать
Вых.Номенклатура КАК Продукция
Поместить ВтПродукция
Из Справочник.СпецификацииНоменклатуры.ВыходныеИзделия КАК Вых
Где Вх.Номенклатура.Код=&КодНом ;

Выбрать Вх.Номенклатура КАК Материал
Поместить ВтМатериалы
Из Справочник.СпецификацииНоменклатуры.ИсходныеКомплектующие КАК Вых
ГДЕ Вых.Номенклатура.Код = &КодПрод;

ВЫБРАТЬ
  Спец.Ссылка КАК Спец,
  Вых.Номенклатура КАК Продукция,
  Вх.Номенклатура КАК Материал
ИЗ
  Справочник.СпецификацииНоменклатуры КАК Спец
      ЛЕВОЕ СОЕДИНЕНИЕ ВтПродукция КАК Вых
      ПО (Вых.Ссылка = Спец.Ссылка)
          И (Вых.НомерСтроки = 1)
      ЛЕВОЕ СОЕДИНЕНИЕ ВтМатериалы КАК Вх
      ПО Спец.Ссылка = Вх.Ссылка
13 MrStomak
 
09.01.13
15:54
Ну только ссылки на спецификации по временных таблицах еще добавить
14 КонецЦикла
 
09.01.13
15:56
Если есть возможность - посмотри план запроса, он подскажет
Мне когда-то помогало поместить в свою табличку с нужными индексами целую таблицу регистра отобранную по условию, а потом уже делать соединение
15 MrStomak
 
09.01.13
15:56
И обращение к Справочник.СпецификацииНоменклатуры в последнем запросе вообще убрать и использовать внутреннее соединение по ссылке таблиц продукции и материалов
16 organizm
 
09.01.13
15:57
(15) последний запрос понравился, только наверно внутренне соединение надо сделать, попробую
17 КонецЦикла
 
09.01.13
15:58
Ха, только заметил что 2 соединения с одной таблицей, с этим-то можно что-то придумать? :)
18 organizm
 
09.01.13
15:58
(14) админы не дают прав к профайлеру (((
19 КонецЦикла
 
09.01.13
16:00
Можно обойтись двумя запросами
В первом поместить нужные элементы во врем. таблицу
В последнем будет одно левое соединение
20 MrStomak
 
09.01.13
16:24
собственно забыл еще одну вещь важную - нужно номенклатуру с нужным кодом поместить во временную таблицу и вместо условия по коду номенклатуры в таблицах материалов и продукции делать внутреннее соединение с этой временной таблицей нужной номенклатуры. В этом случае будет поиск по индексу в табличных частях (если, конечно, для номенклатуры там стоит свойство "Индексировать"), что существенно улучшит приохзводительность при таких объёмах.
21 Lexusss
 
09.01.13
16:30
Без плана запроса все - это гадание на кофейной гуще. Никто никогда не угадает, какой план SQL подберет для выполнения такого извращения.
Можно попробовать уточнить условия за счет явного внутреннего соединения с таб частям, а так же справочником номенклатуры для поиска по коду.

ВЫБРАТЬ
  Спец.Ссылка КАК Спец,
  Вых.Номенклатура КАК Продукция,
  Вх.Номенклатура КАК Материал
ИЗ
  Справочник.СпецификацииНоменклатуры КАК Спец
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.СпецификацииНоменклатуры.ВыходныеИзделия КАК Вых
      ПО Вых.Ссылка = Спец.Ссылка
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК ВыхНоменклатура
ПО ВыхНоменклатура.Ссылка = Вых.Номенклатура
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.СпецификацииНоменклатуры.ИсходныеКомплектующие КАК Вх
      ПО Спец.Ссылка = Вх.Ссылка
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК ВхНоменклатура
ПО ВхНоменклатура.Ссылка = Вх.Номенклатура
ГДЕ
  ВхНоменклатура.Код = &КодНом
  И ВыхНоменклатура.Код = &КодПрод
  И Вых.НомерСтроки = 1
22 Fragster
 
гуру
09.01.13
16:35
Сначала сделать 2 временные таблицы с  ВхНоменклатура.Код = &КодНом и  ВыхНоменклатура.Код = &КодПрод И Вых.НомерСтроки = 1 а потом уже их соединять
23 MrStomak
 
09.01.13
16:38
(21) не будет скана по индексу в этом варианте.
(22) +1
24 GANR
 
09.01.13
16:42
(0)+ (12) Таблицы нужно по возможности фильтровать ПЕРЕД соединением, а не после. Ведь количество сравнений при соединении 2-х таблиц равняется (количество записей левой таблицы) x (количество записей правой таблицы). Выводы делайте сами...
25 GANR
 
09.01.13
16:54
+(1) Ссылка представляет собой кластерный индекс. Поиск по кластерному индексу всегда быстрее чем по некластерному и уж тем более по неиндексированному полю.
26 КонецЦикла
 
09.01.13
17:02
(25) scan по кластерному проиграет seek по некластерному :)
27 Lexusss
 
09.01.13
17:10
(23) Ты протелепатил наполненность индекса по номенклатуре и ссылке в двух таблицах? В индексе по коду номенклатуры, уверен практически на 100%, будет строго 1 запись на значение :)
Так что скорее всего SQL сначала просканит по индексу кода оба раза в справочниках. А вот дальше будет большой вопрос про наполненность: что полезнее - ссылка или номенклатура в Вх и Вых таблицах. И принимать решение принудительно, сидя здесь, далеко от самого сервера - крайне не разумно.
Особливо меня пугает отбор НомерСтроки = 1. Это, скорее всего, и сносит мозг серверу.
(24) MS SQL глубоко наплевать на место наложения отборов при внутреннем соединении.
28 Fragster
 
гуру
09.01.13
17:37
(27) в ТЧ составной индекс на Ссылка + номерстроки, не?
29 GANR
 
09.01.13
17:49
(27) А временные таблицы?
30 Lexusss
 
09.01.13
17:56
(28) Платформа такого индекса не делает. Да и смысла он не имеет. Скорее всего, все равно полезнее будет индекс по номенклатуре.
(29) ВТ позволяют нам игнорировать оптимизатор SQL и фактически самим указывать, как строить план выполнения. В 98% случает у 99% 1Сников так получится гораздо кривее, нежели план выполнения построит сам MS SQL просто по грамотно написанному запросу 1С.
31 Fragster
 
гуру
09.01.13
17:58
(30).1 ну да, там индекс гуид + кейфилд. у меня кейфилд в 99% совпадает с номером строки, а в оставшихся случаях - там всего одна строка. если есть пример с другими данными - прошу.
32 Fragster
 
гуру
09.01.13
18:00
правда при выборке по номеру строки это не поможет, да
33 Lexusss
 
09.01.13
18:05
(31) Вообще то, платформа делает индекс Номенклатура + Ссылка. Как ты умудрился сделать наоборот - незнамо мне... Автору идеально подошел бы индекс НомерСтроки + Номенклатура + Ссылка, но такого платформа не умеет.
Да и, опять же догадываясь, что статистика распределния Справочник.СпецификацииНоменклатуры.ВыходныеИзделия по значениям НомерСтроки будет из серии
1 - 99%
все остальное - 1%, такой индекс не сильно поможет.
34 Fragster
 
гуру
09.01.13
18:07
(33) я бы сделал как в (22)
35 Lexusss
 
09.01.13
18:14
(34) Допустим, у автора всего 20 единиц номенклатуры, 30 000 разными способами формирующимися из разных наборов сырья. Твои хитрые временные таблицы при пересечении сформируют множество в 900 млн строк без индексов. Сервер умрет....
Надо смотреть наполнение конкретных таблиц и статистику их распределения + полюбас план выполнения.
36 MrStomak
 
09.01.13
18:16
(27) Индекс по коду номенклатуры, конечно, будет. Однако, в твоём запросе это нисколько не поможет- сканироваться по коду будет не физическая таблица номенклатуры, у которой индекс по коду есть, а результат запроса к спецификации с неявным соединением на номенклатуру. При этом это неявное соединение с номенклатурой будет без указания условия по коду, что позволило бы отобрать её по индексу - 1С так умно разыменования не интерпретирует.
37 Fragster
 
гуру
09.01.13
18:17
(35) в запросе у автора одна номенклатура.
38 Lexusss
 
09.01.13
20:08
(36) Последовательность соединений и наложения отборов определит SQL сервер по своей статистике, а не разыменования 1С.
(37) Один сорт йогурта получается из одного сорта сырья, но с добавлением сотни разных приправ в разных объемах. Вот и получится таблица много на много.