Есть нетиповая конфа для бэк-офиса. В ней несколько сотен магазинов и несколько десятков тысяч товаров. Ведётся явный партионный учёт. Структура главного регистра остатков примерно следующая:
- Склад;
- Товар;
- Партия;
- Количество;
- Сумма

где Партия- ссылка на элемент одноименного справочника, с данными по серии, поставщику и т.д.

Проблема в том, что запросы к этому регистру остатков выполняются очень медленно, из-за огромного количества партий. Кто-нибудь решал задачи оптимизации подобных систем? Какие решения помогли?
---
1) Все "эксперты", упоминавшие здесь слово "индекс" - RTFM на kb.1c.ru, какие индексы в каких случаях создаются в таблицах итогов регистра накопления.

2) (21) ZLENKO.PRO, Порядок отборов должен соответствовать порядку измерений регистра
Имеется в виду, что нельзя пропускать измерения. Т.е. если есть измерения в порядке Склад-Товар-Партия, то условие виртуальной таблицы по Товар-Партия или Склад-Партия приведет либо к Scan, либо к Seek(predicate), что по сути тоже Scan. А в каком порядке мы пишем условия в скобках - не важно.

По существу вопроса:
0) Следует убедиться, что проблема именно в производительности, а не в параллельности. Оцените Lock asquired по таблицам, участвующим в плане запроса. Если у вас режим автоблокировок - переходите на управляемые. (смотрите текст запроса в трассировке - на это укажут ключи "with serializable" или "with repeatableread")
1) Следует убедиться, что чтения в проблемных запросов выполняются операцией clustered index seek, нет неоптимальных соединений, что в условиях виртуальных таблиц установлены все возможные фильтры. Грубо говоря - смотрите в план, там все видно.
2) Обратите внимание на количество нулевых записей в итогах. http://infostart.ru/public/177538/ - пересчет итогов поможет.
3) Оцените степень фрагментированности целевых таблиц. При необходимости реструктуризуйте. Вообще можно поставить достаточно частый dbcc indexdefrag для целевых таблиц - это не блокирует таблицы.
4) Подумайте о секционировании таблиц, если у вас Enterprise версия SQL.
5) Воздержитесь от использования RLS, это лишние соединения.
6) Обратите внимание на наличие права "закрепление страниц в памяти" для MSSQL, на количество физических чтений при выполнении проблемных запросов в реальных условиях - возможно, имеет смысл добавлять память.
7) Если уж совсем все плохо, можно побить регистры по складам и формировать текст запроса динамически, указывая нужный регистр исходя из условия по складу.

Ключевые рекомендации выделены жирным.
---
sergei_tekh, Склад Партия и Товар являются измерениями, я так понимаю. А в конфигураторе они сделаны индексируемыми полями? Если нет то стоит выставить этот признак, провести реиндексацию базы.
---
sergei_tekh, "Проблема в том, что запросы к этому регистру остатков выполняются очень медленно, из-за огромного количества партий."

Граница итогов по регистру на какую дату расчитана ? Разделение итогов по регистру есть ? Полный пересчет итогов делали ?
---
sergei_tekh, "Кто-нибудь решал задачи оптимизации подобных систем? Какие решения помогли?"

Кстати СУБД какая используется ?
---
sergei_tekh, "Проблема в том, что запросы к этому регистру остатков выполняются очень медленно"

Насколько медленно в секундах ? Сколько товаров в отборе запроса ? Это запрос в отчете или в проведении документов ?
---
sergei_tekh, добавлю до кучи. То, что нужна таблица остатков, а не остатков и оборотов - уже говорили.
Отборы по номенклатуре и складам при получении остатков - установлены?
Еще - немаловажно - в конфигураторе - измерение партии - случайно, не первым идет?
---
медленный запрос в студию
---
platon_,

```1c
    ВЫБРАТЬ
    ПартииОстаткиИОбороты.Товар,
    ПартииОстаткиИОбороты.Партия,
    СУММА(ПартииОстаткиИОбороты.КолвоКонечныйОстаток) КАК Остаток
    ПОМЕСТИТЬ втОстатки
    ИЗ
    РегистрНакопления.Партии.ОстаткиИОбороты(, , , , Склад = &Склад {(Товар).*, (Партия).*}) КАК ПартииОстаткиИОбороты

    СГРУППИРОВАТЬ ПО
    ПартииОстаткиИОбороты.Товар,
    ПартииОстаткиИОбороты.Партия
```
---
sergei_tekh, Тут вопрос совершенно в другом:зачем Вам обороты за весь период работы?Быть может,лучше разделить на 2 запроса (остатки и обороты) и обороты выбрать только за нужный период?
---
sergei_tekh,
В вашем случае достаточно такого запроса

```1c
    ВЫБРАТЬ
    ПартииОстатки.Товар,
    ПартииОстатки.Партия,
    ПартииОстатки.КолвоОстаток КАК Остаток
    ИЗ
    РегистрНакопления.Партии.Остатки(,Склад = &Склад) КАК ПартииОстатки
```
---
Да, запрос не совсем корректный привёл в пример. Но если и выбирать только остатки как в (7), то скорость всё равно очень низкая. Индексы проставлены, итоги периодически расчитываются. Интересуют какие-то координальные изменения структуры конфигурации, которые будут актуальны для большой базы, пускай это даже отрицательно скажется на производительности в момент записи и проведения документов, акцент именно на том, чтобы запросы к регистру партий выполнялись быстрей.
---
sergei_tekh,
Плюс проверьте на какую дату рассчитаны итоги
---
[quote]В приведенных примерах требуется показать все остатки по складу. [/quote]

Вы не внимательны. В (3) на все остатки полученные из СУБД наложен фильтр средствами ядра 1С:
Код{(Товар).*, (Партия).*}Показать полностью
т.е. предполагается фильтр по товару и партии.

У человека проблема в том что он не использует индексы

[quote]Чорд! Это, наверное, на него кто-то (подозреваю, что лично Б.Г. Нуралиев) страшное колдунское проклятье наложил! [/quote]
Зря ерничаете, оффтопик. Человеку досталась самописанная конфа, а он только после ВУЗа.

[quote]А ну-ка, поподробнее, что Вы понимаете под "настроить индекс"? Желательно на примере и все действия по пунктам.[/quote]
В (1) автор топика жирным обозначил проиндексированное измерение регистра. В принципе, для меня это было бы достаточно:
Код
ВЫБРАТЬ РАЗЛИЧНЫЕ
   Партии.Владелец КАК Товар,
   Партии.Ссылка КАК Партия
ПОМЕСТИТЬ втСелекторПартий
{ВЫБРАТЬ
   Товар.*,
   Партия.*}
ИЗ
   Справочник.Партии КАК Партии
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ПартииОстаткиИОбороты.Товар,
    ПартииОстаткиИОбороты.Партия,
    ПартииОстаткиИОбороты.КолвоОстаток КАК Остаток
ПОМЕСТИТЬ втОстатки
ИЗ
   РегистрНакопления.Партии.Остатки(
         ,
         Товар В
               (ВЫБРАТЬ
                  втСелекторПартий.Товар
               ИЗ
                  втСелекторПартий)
            И Партия В
               (ВЫБРАТЬ
                  втСелекторПартий.Партия
               ИЗ
                  втСелекторПартий)) КАК ПартииОстатки
Показать полностью

Что же касается примеров "как настраивать индекс в 1С", то это Вам на видеохостинг, либо классику почитать, вопрос не стоит обсуждения.

[quote]... А вот то, что СУБД пофиг на индексы, когда нужно выбрать значительную долю таблицы, знаете?[/quote]

Конечно знаю. Только человек не админ СУБД SQL, а программист 1С, что очевидно. И случаи когда "нужно выбирать значительную долю таблицы" можно не расматривать просто по статистическому правилу. Большая часть запросов к остаткам - именно селективная, и именно на оптимизации таких запросов и надо сосредотачиваться. Кроме того, если уж вы живете мыслями на SQL.ru, то и должны знать что правильная настройка пары SQL+Кластер 1С в плане разрешенной памяти исключит случаи сваливания в FULL SCAN. Например попробуйте настройку когда 30% ОЗУ ВСЕГДА свободно. )) очень поможет. Но тем не менее - кода 1С вы не привели ни строчки, это наводит на мысли о Вашей низкой квалификации как программиста 1С. И, кстати (36), автор топика склоняется к моим рекомендациям (19)
---
Объясню код запроса (43) для тех кто плохо понимает трехзвенную модель.
1) Первая часть запроса выбирает все партии из СУБД с передачей таблицы партий в кластер 1С, где производится наложение фильтра согласно настроек универсального отчета, после чего отфильтрованная таблица возвращается в СУБД.
2) Вторая часть запроса выбирает остатки из виртуальной таблицы с отбором по предварительно отработавшему фильтру, без передачи ВСЕЙ таблицы остатков из СУБД в кластер. При этом абсолютно пофигу какой из двух высокоселективных индексов будет настроен - Товар, Партия или оба, если настроен, то будет задействован.
3) При этом становится абсолютно пофигу дальнейшее назначение виртуальной таблицы втОстатки - общая логика дальнейшего применения СОХРАНЕНА.

т.е. на выходе - абсолютно рабочий код, не требующий никаких знаний, кроме копипаста.
---
dmurk,
```1c
    РегистрНакопления.Партии.Остатки(
    ,
    Товар В
    (ВЫБРАТЬ
    втСелекторПартий.Товар
    ИЗ
    втСелекторПартий)
    И Партия В
    (ВЫБРАТЬ
    втСелекторПартий.Партия
    ИЗ
    втСелекторПартий)) КАК ПартииОстатки
```

В моей практике отборы виртуальной таблицы в виде запросов показывали низкую производительность. Примером является запрос получения остатков партий в типовых конфигурациях. На эту тему есть ряд публикаций.
---
ZLENKO.PRO,
 Универсальность накладывает свои ограничения - других способов ответить на вопрос не существует. Вопрос (1) не сопровождается конфигурацией для правки, подозреваю и низкую квалификацию вопрошающего. Других способов применить индексы виртуальной таблицы с передачей отбора построителя СУБД -> кластер -> СУБД не существует.

Кроме того, серией тестов проверял - отборы вида Товар = &Параметр либо Товар В (&Параметр) идентичны по производительности конструкции Товар В (ВЫБРАТЬ Товар ИЗ ВиртуальнаяТаблица) при соблюдении следующих условий: служебная таблица tempdb.mdf находится на отдельном SSD диске, виртуальная таблица создана с отметкой ИНДЕКСИРОВАТЬ ПО Товар. При этом статистически верно будет не применять данный индекс, при средней выборке записей в виртуальной таблице менее 50-ти, в этом случае затраты времени на построение индекса будут превышать потери времени от низкой скорости фильтрации таблицы остатков.

Так что и практика, и ряд публикаций хорошо, но ссылки с аргументами ещё лучше. ))
---
dmurk,
подозреваю и низкую квалификацию вопрошающего
Вы в своей квалификации лучше сомневайтесь, пользы больше будет.
Тема была поднята для того, чтобы желающие могли предложить какие-то, возможно нестандартные, идеи для решения этой задачи. А то, что хорошо бы указать явный отбор по всем измерениям регистра, это всем итак понятно (а если что, СКД само всё сделает, перенесёт отборы в параметры виртуальной таблицы и т.д). Речь больше о универсальном отчёте, или о частично универсальном, когда, допустим, пользователь должен в параметрах указать дату начала и окончания анализа, а вот склад, товар и разные свойства партии может указывать, а может и нет. Понятно, что использование таких отчётов нужно минимизировать, но всё же потребность в нём пока есть. Разница между тем, сделаю я предварительно селектор по партиям во временной таблице или не сделаю, очень небольшая - иногда это ускоряет работу, иногда наоборот, но разница в обоих случаях незначительная.
То есть ещё раз, все запросы у меня оптимизированы (ну или почти все), проблема не в них. Тот запрос, что я указал в (3), там да, не было периода, но это из-за того, что я просто из СКД его вытащил, а СКД сам параметры устанавливает.
Примеры решений, которые частично решают проблему я приводил в (10)(11)(13). Хотелось бы конечно услышать что-то в этом духе. Ну нет так нет:)
---
sergei_tekh,

Прошу прощения, если невольно обидел. В условиях ни ответа ни привета, остаются только подозрения ))

Но тем не менее, по Вашему ответу понимаю, что вы не пробовали мой вариант решения (43)?

(43) решает задачу - как избавиться от излишнего обмена между СУБД и кластером 1С на этапе заключительной обработки.

СКД самостоятельно не оптимизирует обращения к виртуальным таблицам, выбирая полную таблицу остатков, и только на этапе приема данных со стороны СУБД выполняя решение - принимать или не принимать данные в память кластера. Тем самым, использование СКД с отборами на стороне кластера излишне перегружает SQL и дисковую подсистему.
---
dmurk,
Но тем не менее, по Вашему ответу понимаю, что вы не пробовали мой вариант решения (43)?
Загружать во временную таблицу селектор партий я конечно же пробовал, но такие запросы выполняются примерно в 5 раз дольше. Пример ниже.
Запрос 1:

```1c
    ВЫБРАТЬ
    Партии.Товар,
    Партии.Склад,
    Партии.Партия,
    Партии.КолвоОстаток
    ИЗ
    РегистрНакопления.Партии.Остатки(
    ,
    Склад = &Склад
    И Партия.СрокГодности < ДАТАВРЕМЯ(2014, 9, 1)) КАК Партии
```

Запрос 2:

```1c
    ВЫБРАТЬ
    Партии.Ссылка КАК Партия
    ПОМЕСТИТЬ втПартии
    ИЗ
    Справочник.Партии КАК Партии
    ГДЕ
    Партии.СрокГодности < ДАТАВРЕМЯ(2014, 9, 1)

    ИНДЕКСИРОВАТЬ ПО
    Партия
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    Партии.Товар,
    Партии.Склад,
    Партии.Партия,
    Партии.КолвоОстаток
    ИЗ
    РегистрНакопления.Партии.Остатки(
    ,
    Склад = &Склад
    И Партия В
    (ВЫБРАТЬ
    вт.Партия
    ИЗ
    втПартии КАК вт)) КАК Партии
```

Первый запрос намного быстрей отрабатывает. Такая же ситуация с обращением к оборотам регистра, в т.ч в разрезе регистратора.
Справочник партий огромный, его ни в коем случае нельзя лишний раз гонять между СУБД и кластером.
---
sergei_tekh,
Первое условие должно быть с максимальной селективностью, и по проиндексированному измерению:
КодВЫБРАТЬ
    Партии.Товар,
    Партии.Склад,
    Партии.Партия,
    Партии.КолвоОстаток
ИЗ
    РегистрНакопления.Партии.Остатки(
            ,
            Партия.СрокГодности < ДАТАВРЕМЯ(2014, 9, 1)
                И Склад = &Склад) КАК ПартииПоказать полностью

т.е. наоборот
---
dmurk, чушь. Проверьте сами - посмотрите в план запроса, переставьте условия и еще раз посмотрите в план.

кстати, я здесь (31) уже об этом писал - п.2
---
Cjuk(55) asved.ru,
Согласен.
---
sergei_tekh,

<quote>
Вы в своей квалификации лучше сомневайтесь, пользы больше будет.
</quote>
Сомневаться в своей квалификации - моя ежедневная задача последние 20 лет. На том стоим ))

<quote>
... А то, что хорошо бы указать явный отбор по всем измерениям регистра, это всем итак понятно (а если что, СКД само всё сделает, перенесёт отборы в параметры виртуальной таблицы и т.д).
</quote>
В том то и дело, что вы ошибочно понимаете суть.

СКД - НЕ ПЕРЕНЕСЕТ ОТБОРЫ В ПАРАМЕТРЫ ВИРТУАЛЬНОЙ ТАБЛИЦЫ.

НА СУБД передается запрос, из которого исключен весь текст, находящийся в фигурных скобках.
---
действительно. зачем вам партии, которые уже списаны? получите остатки по партиям. это будет быстрее. в разы.
---
Допустим, если партию сделать не справочником, а регистром с уникальным кодом партии, такой вариант будет быстрее работать?
---
Или есть ещё идея с разделением базы на 2 части. В первой вести основную работу по добавлению/изменению данных, а во вторую с помощью планов обмена записывать все изменения и использовать только для формирования отчетов.
---
предприятие с большим объёмом партий и движений. отчёт по партиям формируется секунды. правда у нас партии это документы поступления.
странно что у вас так медленно.
---
platon_, "предприятие с большим объёмом партий и движений. отчёт по партиям формируется секунды. правда у нас партии это документы поступления. странно что у вас так медленно."

Если бы партия была составного типа то еще можно было бы предположить что проблема в составном типе измерения Партия.
А тут просто справочник - думаю дело не в структуре регистра а в чем то другом.
---
Ещё идеи:
- отложенное формирование отчётов (ночью с отправкой отчета по почте)
- выделение отдельных регистров, которые не содержат разрез по партиям, или содержат только часть этих данных. Чтобы перенести часть отчётов на них.
---
sergei_tekh, как по мне,то нужно бороться с корнем проблемы,а не делать окопы. Нужно разбираться со структурой регистра,справочника и смотреть железо
---
kofr1c,
Согласен, тут скорее дело не в самом регистре партий, а в железе. Возможно неправильно расставлены индексы (лишние индексы только замедлят выполнение запросов)
---
Данный запрос очень хорошо оптимизируется при добавлении проиндексированного Измерения "ПАРТИИ" в отбор виртуальной таблицы. Сейчас у вас виртуальная таблица отбирается только по складу и передается целиком с SQL звена в кластер 1С, что требует неимоверных объемов памяти, пропускной способности сети и дисковой подсистемы. Как правило такие запросы, как приведенный Вами наблюдаются в системах с постоянным автоподбором партий. Более точно могу сказать глянув конфигурацию. КСТАТИ - неиспользуемые в отборе виртуальных таблиц индексы ВЫКЛЮЧАЙТЕ.
---
Не смущайте человека, писать надо уметь а не железо расковыривать

Партии.ОстаткиИОбороты(, , , , Склад = &Склад {(Товар).*, (Партия).*})

Поясняю ещё раз.
Виртуальная таблица

Правильно примененный индекс на уровне СУБД

Неправильно примененный индекс на уровне кластера 1С

схема автором, хороша для универсального отчета, но никак не для критичных ко времени выполнения обработок.

рекомендации:
1) Индексирование по Складу, Партии оставить - остальные измерения сделать неиндексируемыми.
2) Перед выполнением запроса список партий из документа установить в качестве параметра, например:
Запрос.УстановитьПараметр("ОтборПартий", Товары.ВыгрузитьКолонку("Партия"));
3) В запросе перевести отбор со второго звена на первое, например:
Партии.ОстаткиИОбороты(, , , , Склад = &Склад И Партия В (&ОтборПартий) {(Товар).*, (Партия).*})
4) Отследить чтобы СУБД не сваливалось из режима INDEXED SCAN в режим FULL SCAN - для этого настроить СУБД и кластер следующим образом: СУБД - установить предел выделения памяти 30% от установленного ОЗУ, Кластер 1С - 50% от установленного ОЗУ.
---
dmurk, "Не смущайте человека, писать надо уметь"

Логично. Напишите для начала правильный запрос.
---
ZLENKO.PRO, Что дальше? Умозрительно изложить применение виртуальной таблицы, предположить откуда запрос вызывается??? Или вы потроллить чисто?
---
dmurk, "Что дальше? Умозрительно изложить применение виртуальной таблицы, предположить откуда запрос вызывается??? "

Статистика в базе актуальна ? Как часто выполняется sp_updatestats ? Если идет активное изменение данных в базе то статистику надо обновлять часто. У меня есть пример розничной базы на которой работает несколько крупных супермаркетов - обновление статистики приходится запускать каждые 15 минут.

В базе используются автоматические блокировки или управляемые ? Возможно медленно работает запрос просто потому что он не может их считать т.к. данные заблокированы (если идет транзакционное чтение). Просто в консоли отчетов тоже медленно выполняется запрос ?
---
ZLENKO.PRO, Если идет активное изменение данных в базе то статистику надо обновлять часто

Кстати да, гуглите Trace Flag 2371, если речь об SQL Server 2008 R2 - это ваш случай.
---
dmurk, "Или вы потроллить чисто?"

Я похож на тролля ? Проблемы с оборудованием конечно тоже возможны - положите базу на SATA HDD (а не SAS HDD) диски и сильно потеряете в производительности :-) Но для начала надо проверить наличие чисто программных проблем.
---
dmurk, "Отследить чтобы СУБД не сваливалось из режима INDEXED SCAN в режим FULL SCAN"

Да. Неплохо бы посмотреть план выполнения запроса на уровне СУБД. Возможно это прольет свет на источник проблемы.
---
Пожалуйста. Правильный запрос.

```1c
    ВЫБРАТЬ
    ОстаткиПоПартиям.Товар,
    ОстаткиПоПартиям.Партия,
    ОстаткиПоПартиям.КолвоКонечныйОстаток КАК Остаток
    ПОМЕСТИТЬ втОстатки
    ИЗ
    РегистрНакопления.Партии.Остатки(, Партия В &ОтборПартий И Товар В &ОтборТоваров И Склад = &Склад) КАК ОстаткиПоПартиям
```
---
dmurk, "РегистрНакопления.Партии.Остатки(, Партия В &ОтборПартий И Товар В &ОтборТоваров И Склад = &Склад)"

Порядок отборов должен соответствовать порядку измерений регистра.
---
1) Все "эксперты", упоминавшие здесь слово "индекс" - RTFM на kb.1c.ru, какие индексы в каких случаях создаются в таблицах итогов регистра накопления.

2) (21) ZLENKO.PRO, Порядок отборов должен соответствовать порядку измерений регистра
Имеется в виду, что нельзя пропускать измерения. Т.е. если есть измерения в порядке Склад-Товар-Партия, то условие виртуальной таблицы по Товар-Партия или Склад-Партия приведет либо к Scan, либо к Seek(predicate), что по сути тоже Scan. А в каком порядке мы пишем условия в скобках - не важно.

По существу вопроса:
0) Следует убедиться, что проблема именно в производительности, а не в параллельности. Оцените Lock asquired по таблицам, участвующим в плане запроса. Если у вас режим автоблокировок - переходите на управляемые. (смотрите текст запроса в трассировке - на это укажут ключи "with serializable" или "with repeatableread")
1) Следует убедиться, что чтения в проблемных запросов выполняются операцией clustered index seek, нет неоптимальных соединений, что в условиях виртуальных таблиц установлены все возможные фильтры. Грубо говоря - смотрите в план, там все видно.
2) Обратите внимание на количество нулевых записей в итогах. http://infostart.ru/public/177538/ - пересчет итогов поможет.
3) Оцените степень фрагментированности целевых таблиц. При необходимости реструктуризуйте. Вообще можно поставить достаточно частый dbcc indexdefrag для целевых таблиц - это не блокирует таблицы.
4) Подумайте о секционировании таблиц, если у вас Enterprise версия SQL.
5) Воздержитесь от использования RLS, это лишние соединения.
6) Обратите внимание на наличие права "закрепление страниц в памяти" для MSSQL, на количество физических чтений при выполнении проблемных запросов в реальных условиях - возможно, имеет смысл добавлять память.
7) Если уж совсем все плохо, можно побить регистры по складам и формировать текст запроса динамически, указывая нужный регистр исходя из условия по складу.

Ключевые рекомендации выделены жирным.
---
Извините что отдельными сообщениями запостил, но иначе все смешалось бы в кучу, а надо же "разложить по полочкам".
---
ЗЫ думаю, про индексы полезно написать здесь:

Таблица итогов - это кластеризованный индекс по полям в следующем порядке:
1) разделитель данных
2) период
3) измерения в порядке, как они заданы в конфигураторе.

Если мы ставим в измерении флажок "индексировать", то добавляется НЕКЛАСТЕРИЗОВАННЫЙ индекс вида
1) наше измерение
2) разделитель данных
3) период
4) измерения в порядке, как они заданы в конфигураторе, при этом наше измерение не исключается.

Операция же Nonclustered index seek применительно к таблице итогов однозначно влечет за собой Lookup, и далеко не факт, что это окажется производительнее seek(predicate), да и индекс по двум измерениям мы так не сделаем - получатся два разных индекса вышеописанного вида.

Так что при невозможности выставить правильный порядок измерений регистра единственный путь - нарушать лицензионное соглашение и создавать требуемый индекс вручную, не забывая, что при реструктуризации 1С его грохнет.
---
asved.ru,

Пишете галиматью, не имеющую отношения к вопросу. У человека проблема в том что он не использует индексы. Вообще. Ему нужен текст запроса который будет использовать индексы. Проблема кластерных индексов регистров накопления - низкая предсказуемость попадания, плюс неориентированность кластерного индекса на решение задач выборки данных для заданного отчета. Основное поле кластерного индекса - Период в отчете не использовано вообще. То есть никак (1). Ответ даете на уровень профессионального программиста T-SQL, простите - а собеседник - кто? А если база - файловая? А может просто нужно задействовать индекс с высокой селективностью, - и этого будет _ДОСТАТОЧНО_? У каждого решения есть своя стоимость. Настроить индекс, добавить отбор в запрос - решение на уровне 15$. Расковырять СУБД - 200$ и регулярный контроль "ручных" индексов - ещё 50$ каждый месяц. Разница по производительности между первым и вторым - 10%. Ещё раз, что за нетехнологичные решения вы предлагаете нормальным людям?
---
dmurk, Вы для начала задайтесь вопросом - а что человеку нужно. В приведенных примерах требуется показать все остатки по складу.

У человека проблема в том что он не использует индексы
Чорд! Это, наверное, на него кто-то (подозреваю, что лично Б.Г. Нуралиев) страшное колдунское проклятье наложил!

Основное поле кластерного индекса - Период в отчете не использовано вообще
Вообще-то это нормально для случая выборки актуальных итогов. (загляните в таблицу итогов регистра - видите там записи с период = 4999 год? ну так это они и есть).
И если уж на то пошло, то первым полем любого кластерного индекса в 1С является разделитель данных.

Настроить индекс
А ну-ка, поподробнее, что Вы понимаете под "настроить индекс"? Желательно на примере и все действия по пунктам.

А если база - файловая?
То на означенных ТС объемах она уже сдохла и плохо пахнет.

А может просто нужно задействовать индекс с высокой селективностью, - и этого будет _ДОСТАТОЧНО_?
А может, и нет. Все зависит от результата, который мы хотим получить при исполнении запроса.
Что такое селективность индекса, я вижу, Вы слышали. А вот то, что СУБД пофиг на индексы, когда нужно выбрать значительную долю таблицы, знаете? И что решение это СУБД принимает на основании статистик.
---
ЗЗЫ Вообще уже несколько месяцев как есть вменяемый комплексный источник информации по теме: http://www.1c.ru/news/info.jsp?id=17973

Там, правда, тащ Филиппов открыл новый уровень изоляции транзакций ;) ну и еще некоторые моменты я бы поправил и уточнил, но в целом - вещь крайне полезная.
---
Автор топика не хочет поделиться результатами ?
---
ZLENKO.PRO, к сожалению, я ничего не могу сделать со своей базой на уровне СуБД, нет никаких знаний на эту тему. Для начала, думаю, нужно отходить от практики использования универсального отчёта, чтобы были четкие отборы по виртуальным таблицам. Ну и протестировать разные варианты с индексированием.
---
sergei_tekh, "Для начала, думаю, нужно отходить от практики использования универсального отчёта"

Думаю это неверный путь решения проблемы...

"я ничего не могу сделать со своей базой на уровне СуБД, нет никаких знаний на эту тему"

Не вижу препятствий для решения этой проблемы.
---
sergei_tekh

Странно, если у вас нет возможности решать вопрос на уровне СУБД, почему тогда вы отмечаете ответ как лучший, при наличии приведенного текста запроса (19), который однозначно поднимет производительность в 20-25 раз? Вы не пробовали применить мои рекомендации?
---
dmurk, при наличии приведенного текста запроса (19), который однозначно поднимет производительность в 20-25 раз?

А если нам нужно выбрать ВСЕ остатки, как Ваш запрос повлияет на производительность, знаете?

А я знаю: ухудшит. За счет двух лишних соединений при формировании виртуальной таблицы.
---
asved.ru,

"Есть нетиповая конфа для бэк-офиса. В ней несколько сотен магазинов и несколько десятков тысяч товаров. Ведётся явный партионный учёт"

Ваше предположение является нежизнеспособным. Универсальный отчет по ВСЕМ остаткам имеет нулевую юзабилити, тем более во время работы других пользователей, когда постоянно меняются данные об остатках. Пользователю который формирует такого монстра единственное что нужно - это CTRL+Break, а такое во время запроса не поддерживается. Не забывайте так же, что получателем результатов является поле табличного документа куда вы не сможете впихнуть ВСЕ ОСТАТКИ. Корректно работать с такого рода информацией только через динамические списки с порционным чтением, но речь идет об обычном интерфейсе.

Универсальный отчет обо всех остатках формируют только малоопытные пользователи, начинающие осваивать 1С. Для выгрузки остатков в технологических целях приведенный текст запроса - неприменим.
---
asved.ru, "А если нам нужно выбрать ВСЕ остатки, как Ваш запрос повлияет на производительность, знаете?"

А если нам не нужно выбирать ВСЕ остатки ? :-)
---
Была проблема с размером базы (УТ) и соответственно низкая производительность отчетов по регистру ПартииТоваровНаСкладах из-за его размера. было принято решение сворачивать движения помесячно, к примеру вместо 10 записей документов на списание одного товара по одной пратии, формировалась 1 запись со списанием 10 шт. Свертка движений проходила помесячно за предыдущие периоды, поскольку все равно все отчеты за прошлый период просматривались с мин интервалом в месяц. Таким образом сворачивали несколько самых больших регистров, тем самым уменьшили размер базы и увеличили скорость выборки оборотов по регистру.
---
В данном случае построение предварительного индекса, не имеет смысла.

Это необходимо только если у вас накладывается внешний фильтр {(Товар).*, (Партия).*}