Имя: Пароль:
1C
 
Хэш или не хэш.
0 H A D G E H O G s
 
29.10.14
12:53
Дня доброго.
Есть дилемма:

Что благородней духом - покоряться
Пращам и стрелам яростной судьбы
Иль, ополчась на море смут, сразить их?

Есть товары и комплекты.
Комплекты определены отдельным регистром сведений, следующей структуры:

Комплект (Справочник.Номенклатура)
СерияКомплекта (Справочник.СерияНоменклатуры)
ХарактеристикаКомплекта (Справочник.ХарактеристикаНоменклатуры)
Номеклатура (Справочник.Номенклатура) (комплектующее)
СерияНоменклутуры (Справочник.СерияНоменклатуры)
ХарактеристикаНоменклутуры (Справочник.ХарактеристикаНоменклатуры)



В момент проведения нужно разложить комплекты на комплектующие, а потом со сводной таблицей обычных товаров и комплектующих делать разные вещи как в запросах, так и в програмном коде.

Соотнесение комплектов и комплектующих выглядит так:

ТаблицаНоменклатурХарактеристикИСерий КАК ТаблицаНоменклатурХарактеристикИСерий
ВНУТРЕННЕЕ СОЕДИНЕНИЕ КомплектыИКомплектующие КАК КомплектыИКомплектующие
ПО ТаблицаНоменклатурХарактеристикИСерий.Номенклатура = КомплектыИКомплектующие.Комплект
И ТаблицаНоменклатурХарактеристикИСерий.СерияНоменклатуры = КомплектыИКомплектующие.СерияКомплекта
И ТаблицаНоменклатурХарактеристикИСерий.ХарактеристикаНоменклатуры = КомплектыИКомплектующие.ХарактеристикаКомплекта

Это соединение будет часто и много.

И вот у меня мысль - заменить его на соединение по хэшу вручную.
50 H A D G E H O G s
 
29.10.14
14:13
51 H A D G E H O G s
 
29.10.14
14:13
(50) Этот метод мне не подходит.
52 Serginio1
 
29.10.14
14:14
(48) А это большой разницы то не играет. Проосто количество сравнений будет меньше. И в основном только полю ХешСвязи
53 H A D G E H O G s
 
29.10.14
14:14
(52) Там же И а не ИЛИ.

Проверяться на равенство будут все поля.
54 Serginio1
 
29.10.14
14:16
(53) Проверяться на равенство будут все поля, когда найдется ныжный ХешСвязи. Есть разница.
55 Serginio1
 
29.10.14
14:17
54 вспомни роль первого поля в индексе
56 H A D G E H O G s
 
29.10.14
14:18
(55) Ааа, индексы.

Я не буду накладывать индекс.
57 H A D G E H O G s
 
29.10.14
14:19
(55) Я уж офигеть успел.
58 H A D G E H O G s
 
29.10.14
14:20
(49) "ТОЛЬКО в паре с двумя регламентнымы заданиями которые перерасчитывали хеши комплектов и хеши прав"

Хеши хранились в табличной части, в БД?
59 H A D G E H O G s
 
29.10.14
14:20
(58) Почему пересчет Регламентами, а не ПередЗаписью?
60 Serginio1
 
29.10.14
14:22
(56) Так тебе достаточно только неуникального индекса на ХешСвязи
61 H A D G E H O G s
 
29.10.14
14:24
(60) Не понял.
62 H A D G E H O G s
 
29.10.14
14:25
(60) Но за идею с индексом - респект и уважуха тебе, я сам до такого недопетрил.
63 vde69
 
29.10.14
14:26
(58) хеш хранился в наименовании элемента справочника, а в ТЧ все элементы.

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

Рег задания нужны для формирования элементов справочника (их делал с избытком) и для записи регистра ключей, почему рег задание - для того, что-бы не тормозило и выполнялось в отдельной транзакции.

документы проводились быстро а потов (в течении минуты) формировались элементы и дополнительные записи регистра на который потом шел RLS
64 vde69
 
29.10.14
14:27
(63)+ у меня эта система формировала доступ примерно по 15 различным параметрам
65 H A D G E H O G s
 
29.10.14
14:31
(63) Хеш как строился?
66 vde69
 
29.10.14
14:35
(65)
1. делаю таблицу с элементами, для ссылочных беру их идентификаторы
2. сортирую по текстовому идентификатору
3. объеденяю в одну строку (через запятую) все идентификаторы
4. из строки, по MD-5, получаю хеш
67 H A D G E H O G s
 
29.10.14
14:36
(66) Коллизии, что с ними?
68 vde69
 
29.10.14
14:36
Функция Из_Число_В_16(Знач Значение)
    Результат = "";
    Пока Значение > 0 Цикл
        Остат = Значение % 16;
        Значение = (Значение - Остат) / 16;
        Результат = Сред("0123456789ABCDEF", Остат + 1, 1) + Результат
    КонецЦикла;
    
    Возврат Результат
КонецФункции

Функция ХэшБлоками(Строка, ДлинаБлока = 10, hash = 0, M = 31, TABLE_SIZE = 18446744073709551616)
    
    НачПозиция = 1;
    ДлинаСтроки = СтрДлина(Строка);
    Пока НачПозиция <= ДлинаСтроки Цикл
        СтрокаБлока = Сред(Строка, НачПозиция, ДлинаБлока);
        Для к = 1 По СтрДлина(СтрокаБлока) Цикл
            hash = M * hash + КодСимвола(СтрокаБлока, к)
        КонецЦикла;
        hash = hash % TABLE_SIZE;
        НачПозиция = НачПозиция + ДлинаБлока
    КонецЦикла;
    
    Возврат hash
КонецФункции

Функция ПолучитьХешТаблицы (ТЗ) Экспорт
    Результат = "";
    
    // работаем с копией
    мТЗ = ТЗ.Скопировать();
    
    // приведем порядок ТЗ к единообразию
    // это исключит проблеммы с разным порядком элементов
    мТЗ.Колонки.Добавить("СтрокаДляХеш");
    ТипБулево = ТипЗнч(Истина);
    Для каждого эл Из мТЗ Цикл
        Если ТипЗнч(эл.Объект) = Тип("ПеречислениеСсылка.ВидыИерархииДоступа") Тогда
            
            ИмяПеречисления = эл.Объект.Метаданные().Имя;
            ИндексЗначенияПеречисления = Перечисления[ИмяПеречисления].Индекс(эл.Объект);
            ИмяЗначенияПеречисления = Метаданные.Перечисления[ИмяПеречисления].ЗначенияПеречисления[ИндексЗначенияПеречисления].Имя;            
            
            эл.СтрокаДляХеш = СокрЛП(эл.Объект.Метаданные().ПолноеИмя()) + "." + ИмяЗначенияПеречисления;
        Иначе
            эл.СтрокаДляХеш = СокрЛП(эл.Объект.УникальныйИдентификатор());
        КонецЕсли;
    КонецЦикла;     
    мТЗ.Сортировать ("СтрокаДляХеш");
    
    // теперь строим строку для хеширования
    СтрокаСпискаДаных = "";
    Для каждого эл Из мТЗ Цикл
        СтрокаСпискаДаных = СтрокаСпискаДаных + эл.СтрокаДляХеш + ";";
    КонецЦикла;     
    
    //ВнешняяКомпонента = Новый COMОбъект("CAPICOM.HashedData");
    //ВнешняяКомпонента.Algorithm = 3;
    //ВнешняяКомпонента.Hash(СтрокаСпискаДаных);
    //Результат = ВнешняяКомпонента.Value;
    //ВнешняяКомпонента = Неопределено;
    //
    // на 64х сервере работать не будет, нужно что-то придумать другое
    // типа:
    //
    //Dim sha As New SHA1CryptoServiceProvider()
    //Dim result As Byte() = sha.ComputeHash(dataArray)
    //
    // Пока сделал встроеным языком
    //
    
    Результат = Из_Число_В_16(ХэшБлоками(СтрокаСпискаДаных, 5381, 33));
    
    Возврат Результат;
КонецФункции
69 H A D G E H O G s
 
29.10.14
14:37
Все, сделаю 2 режима - без коллизий и с коллизиями...
70 H A D G E H O G s
 
29.10.14
14:37
(68) Гыгыгы...

Функция РазложитьСтруктуруАдресаВСтрокуДляХеша(СтруктураАдреса)
    МассивПолей=Новый Массив;
    МассивПолей.Добавить("КодСтраны");
    МассивПолей.Добавить("Страна");
    МассивПолей.Добавить("Индекс");
    МассивПолей.Добавить("КодРегиона");
    МассивПолей.Добавить("Регион");
    МассивПолей.Добавить("Район");
    МассивПолей.Добавить("Город");
    МассивПолей.Добавить("НаселенныйПункт");
    МассивПолей.Добавить("Улица");
    МассивПолей.Добавить("Дом");
    МассивПолей.Добавить("Корпус");
    МассивПолей.Добавить("Квартира");
    МассивПолей.Добавить("ЭтоРоссийскийАдрес");
    МассивПолей.Добавить("Представление");
    СтрокаДанных="";
    Для Каждого ЭлементМассива Из МассивПолей Цикл
        Если СтруктураАдреса.Свойство(ЭлементМассива) Тогда
            СтрокаДанных=СтрокаДанных+XMLСтрока(СтруктураАдреса[ЭлементМассива]);
        КонецЕсли;
    КонецЦикла;
    Возврат СтрокаДанных;
КонецФункции

Функция ПолучитьХешДляДанных(Данные) Экспорт
    СтрокаДанных="";
    Если ТипЗнч(Данные)=Тип("Структура") Тогда // Адрес
        СтрокаДанных=СтрокаДанных+РазложитьСтруктуруАдресаВСтрокуДляХеша(Данные);
    Иначе
        Для Каждого ЭлементМассива Из Данные Цикл
            Если ТипЗнч(ЭлементМассива)=Тип("Структура") Тогда //Адрес в массиве
                Если НЕ ЭлементМассива.Свойство("Хеш") Тогда
                    ЭлементМассива.Вставить("Хеш",ПолучитьХешДляДанных(ЭлементМассива));
                КонецЕсли;
                СтрокаДанных=СтрокаДанных+ЭлементМассива.Хеш;
            Иначе
                СтрокаДанных=СтрокаДанных+XMLСтрока(ЭлементМассива);
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    Если СтрокаДанных="" Тогда
        Возврат "";
    КонецЕсли;
    Информация=Новый СистемнаяИнформация;
    ЭтоПлатформа83=Лев(Информация.ВерсияПриложения,3)="8.3";
    Если ЭтоПлатформа83 Тогда
        Хеширование=Неопределено;
        ВЫПОЛНИТЬ("Хеширование=Новый ХешированиеДанных(ХешФункция.MD5)"); //Простите меня за Выполнить
        Хеширование.Добавить(СтрокаДанных);
        Возврат СтрЗаменить(Хеширование.ХешСумма, " ", "");
    Иначе
        ДлинаСтроки = СтрДлина(СтрокаДанных);
        ЗначениеM=33;
        ХешСумма=5381;
        Для Счетчик=1 По ДлинаСтроки Цикл
            ХешСумма = ЗначениеM * ХешСумма + КодСимвола(Сред(СтрокаДанных,Счетчик,1));
        КонецЦикла;
        ХешСумма=ХешСумма%18446744073709551616;
        ХешСумма=Формат(ХешСумма,"ЧГ=");
        Возврат ХешСумма;
    КонецЕсли;
КонецФункции
71 H A D G E H O G s
 
29.10.14
14:38
(69) Наличие коллизий буду определять сверткой ТЗ по полю ХешСвязи.
72 vde69
 
29.10.14
14:40
(67) я прикидывал вероятности, для моей системы она было очень низкая, примерно 1 коллизия на 10 лет...

по этому я вообще ничего не делал...

самое простое это увеличивать длинну хеша, тем самым уменьшим вероятность колизии
73 H A D G E H O G s
 
29.10.14
14:41
vde, как боролся с коллизиями?
74 H A D G E H O G s
 
29.10.14
14:41
(72) Ясн.
75 Сергиус
 
29.10.14
15:08
(0) А что у тебя в колонке ХешСвязи? Как ты его(хеш) вычисляешь?
76 H A D G E H O G s
 
29.10.14
15:16
(75) Строка, помещаю для каждой строки связку Номенклатура, Характеристика, Серия и строю для массива по (70)
77 Serginio1
 
29.10.14
15:28
(73) А зачем с ними бороться. Индекс по полю ХешСвязи и сравнение полей все разруливает. Наоборот стоит держать даже небольшой хэш (инт) для скорости поиска за счет увеличения  плотности ключей на странице
78 Ник второй
 
29.10.14
15:30
(76) Там наименование?
79 H A D G E H O G s
 
29.10.14
15:30
(78) Там ссылки
80 H A D G E H O G s
 
29.10.14
15:31
(77) "небольшой хэш (инт)"

Скажи это 1С с их MD5 в виде строки.
81 H A D G E H O G s
 
29.10.14
15:31
(77) Почти уверен, что будет IndexScan
82 H A D G E H O G s
 
29.10.14
15:31
(81) И индекс не поможет в борьбе с коллизиями.
83 H A D G E H O G s
 
29.10.14
15:32
(82) Вернее, не в борьбе а в оптимизации, будет сравнение по 4 полям.
84 Ник второй
 
29.10.14
15:32
(81) Будет seek .... where  и то только в том случае если по хешу не найдет.....
85 Ник второй
 
29.10.14
15:33
(84) Точнее если найдет ))) и там ветка будет одна
86 Ник второй
 
29.10.14
15:34
Интересные вещи копаете господа, взял на заметку )
87 H A D G E H O G s
 
29.10.14
15:34
(84) Только в случае nested loops, но будет hashjoin
88 H A D G E H O G s
 
29.10.14
15:35
Новая версия

ТаблицаХешейСвязи=ТаблицаНоменклатурХарактеристикИСерий.Скопировать(,"ХешСвязи");
        НачальноеКоличествоСтрокТаблицыХешейСвязи=ТаблицаХешейСвязи.Количество();
        ТаблицаХешейСвязи.Свернуть("ХешСвязи");
        ЕстьКоллизии=ТаблицаХешейСвязи.Количество()<>НачальноеКоличествоСтрокТаблицыХешейСвязи; //Вероятность крайне мала
        Если ЕстьКоллизии Тогда
            ТаблицаНоменклатурХарактеристикИСерий.ЗаполнитьЗначения("","ХешСвязи"); //Обнулим, дабы не тащить в SQL
        КонецЕсли;
        
        Запрос=Новый Запрос;
        Запрос.МенеджерВременныхТаблиц=МенеджерВТ;
        Запрос.Текст=
        "ВЫБРАТЬ
        |    ВЫРАЗИТЬ(ТаблицаНоменклатурХарактеристикИСерий.Номенклатура КАК Справочник.Номенклатура) КАК Номенклатура,
        |    ВЫРАЗИТЬ(ТаблицаНоменклатурХарактеристикИСерий.СерияНоменклатуры КАК Справочник.СерииНоменклатуры) КАК СерияНоменклатуры,
        |    ВЫРАЗИТЬ(ТаблицаНоменклатурХарактеристикИСерий.ХарактеристикаНоменклатуры КАК Справочник.ХарактеристикиНоменклатуры) КАК ХарактеристикаНоменклатуры,
        |    ВЫРАЗИТЬ(ТаблицаНоменклатурХарактеристикИСерий.ИндексТабличнойЧасти КАК ЧИСЛО(2, 0)) КАК ИндексТабличнойЧасти,
        |    ВЫРАЗИТЬ(ТаблицаНоменклатурХарактеристикИСерий.ДатаСреза КАК ДАТА) КАК ДатаСреза,
        |    ВЫРАЗИТЬ(ТаблицаНоменклатурХарактеристикИСерий.НомерСтроки КАК ЧИСЛО(5, 0)) КАК НомерСтроки,
        |    ВЫРАЗИТЬ(ТаблицаНоменклатурХарактеристикИСерий.ХешСвязи КАК СТРОКА) КАК ХешСвязи
        |ПОМЕСТИТЬ ТаблицаНоменклатурХарактеристикИСерий
        |ИЗ
        |    &ТаблицаНоменклатурХарактеристикИСерий КАК ТаблицаНоменклатурХарактеристикИСерий
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    ТаблицаНоменклатурХарактеристикИСерий.Номенклатура КАК Комплект,
        |    ТаблицаНоменклатурХарактеристикИСерий.СерияНоменклатуры КАК СерияКомплекта,
        |    ТаблицаНоменклатурХарактеристикИСерий.ХарактеристикаНоменклатуры КАК ХарактеристикаКомплекта,
        |    алкКомплектующиеСерийНоменклатуры.Номенклатура,
        |    алкКомплектующиеСерийНоменклатуры.ХарактеристикаНоменклатуры,
        |    алкКомплектующиеСерийНоменклатуры.СерияНоменклатуры
        |ИЗ
        |    РегистрСведений.алкКомплектующиеСерийНоменклатуры КАК алкКомплектующиеСерийНоменклатуры
        |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаНоменклатурХарактеристикИСерий КАК ТаблицаНоменклатурХарактеристикИСерий
        |        ПО алкКомплектующиеСерийНоменклатуры.Комплект = ТаблицаНоменклатурХарактеристикИСерий.Номенклатура
        |            И алкКомплектующиеСерийНоменклатуры.СерияКомплекта = ТаблицаНоменклатурХарактеристикИСерий.СерияНоменклатуры
        |            И алкКомплектующиеСерийНоменклатуры.ХарактеристикаКомплекта = ТаблицаНоменклатурХарактеристикИСерий.ХарактеристикаНоменклатуры
        |            И (ВЫБОР
        |                КОГДА &ОрганизацияЗаполнена
        |                    ТОГДА алкКомплектующиеСерийНоменклатуры.Организация = &Организация
        |                ИНАЧЕ ИСТИНА
        |            КОНЕЦ)";
        
        Запрос.УстановитьПараметр("ТаблицаНоменклатурХарактеристикИСерий",ТаблицаНоменклатурХарактеристикИСерий);
        Организация=Неопределено;
        Если МетаданныеДокумента.Реквизиты.Найти("Организация")<>Неопределено Тогда
            Организация=ДокументОбъект.Организация;
        КонецЕсли;
        Запрос.УстановитьПараметр("Организация",Организация);
        Запрос.УстановитьПараметр("ОрганизацияЗаполнена",ЗначениеЗаполнено(Организация));
        ТаблицаКомплектовИКомплектующих=Запрос.Выполнить().Выгрузить();
        ТаблицаКомплектовИКомплектующих.Колонки.Добавить("ХешСвязи",Новый ОписаниеТипов("Строка"));
        
        Если Не ЕстьКоллизии Тогда
            Для Каждого СтрокаТаблицыКомплектовИКомплектующих Из ТаблицаКомплектовИКомплектующих Цикл
                МассивДанныхДляХеша=Новый Массив;
                МассивДанныхДляХеша.Добавить(СтрокаТаблицыКомплектовИКомплектующих.Комплект);
                МассивДанныхДляХеша.Добавить(СтрокаТаблицыКомплектовИКомплектующих.ХарактеристикаКомплекта);
                МассивДанныхДляХеша.Добавить(СтрокаТаблицыКомплектовИКомплектующих.СерияКомплекта);
                СтрокаТаблицыКомплектовИКомплектующих.ХешСвязи=алкОбщегоНазначенияКлиентСервер.ПолучитьХешДляДанных(МассивДанныхДляХеша);
            КонецЦикла;
            ТаблицаХешейСвязи=ТаблицаКомплектовИКомплектующих.Скопировать(,"ХешСвязи");
            НачальноеКоличествоСтрокТаблицыХешейСвязи=ТаблицаХешейСвязи.Количество();
            ТаблицаХешейСвязи.Свернуть("ХешСвязи");
            ЕстьКоллизии=ТаблицаХешейСвязи.Количество()<>НачальноеКоличествоСтрокТаблицыХешейСвязи; //Вероятность крайне мала
            Если ЕстьКоллизии Тогда
                ТаблицаКомплектовИКомплектующих.ЗаполнитьЗначения("","ХешСвязи"); //Обнулим, дабы не тащить в SQL
            КонецЕсли;
        КонецЕсли;
        
        Запрос.УстановитьПараметр("ЕстьКоллизии",ЕстьКоллизии);

        Запрос.Текст=
        "ВЫБРАТЬ
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.Номенклатура КАК Справочник.Номенклатура) КАК Номенклатура,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.СерияНоменклатуры КАК Справочник.СерииНоменклатуры) КАК СерияНоменклатуры,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.ХарактеристикаНоменклатуры КАК Справочник.ХарактеристикиНоменклатуры) КАК ХарактеристикаНоменклатуры,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.Комплект КАК Справочник.Номенклатура) КАК Комплект,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.СерияКомплекта КАК Справочник.СерииНоменклатуры) КАК СерияКомплекта,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.ХарактеристикаКомплекта КАК Справочник.ХарактеристикиНоменклатуры) КАК ХарактеристикаКомплекта,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.ХешСвязи КАК СТРОКА) КАК ХешСвязи
        |ПОМЕСТИТЬ ТаблицаКомплектовИКомплектующих
        |ИЗ
        |    &ТаблицаКомплектовИКомплектующих КАК ТаблицаКомплектовИКомплектующих
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    ТаблицаНоменклатурХарактеристикИСерий.ИндексТабличнойЧасти,
        |    ТаблицаНоменклатурХарактеристикИСерий.НомерСтроки,
        |    ТаблицаНоменклатурХарактеристикИСерий.ДатаСреза,
        |    ТаблицаНоменклатурХарактеристикИСерий.ХешСвязи,
        |    ЕСТЬNULL(ТаблицаКомплектовИКомплектующих.Номенклатура, ТаблицаНоменклатурХарактеристикИСерий.Номенклатура) КАК Номенклатура,
        |    ЕСТЬNULL(ТаблицаКомплектовИКомплектующих.ХарактеристикаНоменклатуры, ТаблицаНоменклатурХарактеристикИСерий.ХарактеристикаНоменклатуры) КАК ХарактеристикаНоменклатуры,
        |    ЕСТЬNULL(ТаблицаКомплектовИКомплектующих.СерияНоменклатуры, ТаблицаНоменклатурХарактеристикИСерий.СерияНоменклатуры) КАК СерияНоменклатуры
        |ПОМЕСТИТЬ ТаблицаНоменклатурХарактеристикИСерийСКомплектующими
        |ИЗ
        |    ТаблицаНоменклатурХарактеристикИСерий КАК ТаблицаНоменклатурХарактеристикИСерий
        |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаКомплектовИКомплектующих КАК ТаблицаКомплектовИКомплектующих
        |        ПО (&ЕстьКоллизии = ИСТИНА
        |                    И ТаблицаНоменклатурХарактеристикИСерий.Номенклатура = ТаблицаКомплектовИКомплектующих.Комплект
        |                    И ТаблицаНоменклатурХарактеристикИСерий.СерияНоменклатуры = ТаблицаКомплектовИКомплектующих.СерияКомплекта
        |                    И ТаблицаНоменклатурХарактеристикИСерий.ХарактеристикаНоменклатуры = ТаблицаКомплектовИКомплектующих.ХарактеристикаКомплекта
        |                ИЛИ &ЕстьКоллизии = ЛОЖЬ
        |                    И ТаблицаНоменклатурХарактеристикИСерий.ХешСвязи = ТаблицаКомплектовИКомплектующих.ХешСвязи)
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.ИндексТабличнойЧасти КАК ИндексТабличнойЧасти,
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.НомерСтроки КАК НомерСтроки,
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.ДатаСреза КАК ДатаСреза,
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.ХешСвязи,
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.Номенклатура КАК Номенклатура,
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.ХарактеристикаНоменклатуры,
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.СерияНоменклатуры КАК СерияНоменклатуры,
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.Номенклатура.алкКрепость КАК Крепость,
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.Номенклатура.алкЕмкость КАК Емкость,
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.Номенклатура.алкТипПродукции КАК ТипПродукции,
        |    ВЫБОР
        |        КОГДА ЕСТЬNULL(ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.СерияНоменклатуры.алкВидПродукции, НЕОПРЕДЕЛЕНО) В (НЕОПРЕДЕЛЕНО, ЗНАЧЕНИЕ(Справочник.алкВидыАлкогольнойПродукции.ПустаяСсылка))
        |            ТОГДА ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.Номенклатура.алкВидПродукции
        |        ИНАЧЕ ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.СерияНоменклатуры.алкВидПродукции
        |    КОНЕЦ КАК ВидПродукции,
        |    ВЫБОР
        |        КОГДА ЕСТЬNULL(ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.СерияНоменклатуры.алкПроизводитель, НЕОПРЕДЕЛЕНО) В (НЕОПРЕДЕЛЕНО, ЗНАЧЕНИЕ(Справочник.Организации.ПустаяСсылка), ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка))
        |            ТОГДА ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.Номенклатура.алкПроизводитель
        |        ИНАЧЕ ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.СерияНоменклатуры.алкПроизводитель
        |    КОНЕЦ КАК Производитель,
        |    ВЫБОР
        |        КОГДА ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.Номенклатура.алкИмпорт
        |            ТОГДА ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.СерияНоменклатуры.алкСертификатСоответствия
        |        ИНАЧЕ ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.СерияНоменклатуры.алкСертификатПроисхождения
        |    КОНЕЦ КАК Сертификат,
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.Номенклатура.алкИмпорт КАК Импорт,
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.Номенклатура.алкАнализыДляУдостоверенияОКачестве КАК АнализыДляУдостоверенияОКачестве
        |ПОМЕСТИТЬ ТаблицаАлкогольныхНоменклатур
        |ИЗ
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими КАК ТаблицаНоменклатурХарактеристикИСерийСКомплектующими
        |ГДЕ
        |    ТаблицаНоменклатурХарактеристикИСерийСКомплектующими.Номенклатура.ВидНоменклатуры.алкВидЭлементаТМЦ = ЗНАЧЕНИЕ(Перечисление.алкВидыЭлементовТМЦ.Алкоголь)
        |
        |ИНДЕКСИРОВАТЬ ПО
        |    Номенклатура
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    ТаблицаАлкогольныхНоменклатур.ИндексТабличнойЧасти,
        |    ТаблицаАлкогольныхНоменклатур.НомерСтроки,
        |    ТаблицаАлкогольныхНоменклатур.Номенклатура,
        |    ТаблицаАлкогольныхНоменклатур.ХешСвязи,
        |    ТаблицаАлкогольныхНоменклатур.ХарактеристикаНоменклатуры,
        |    ТаблицаАлкогольныхНоменклатур.СерияНоменклатуры,
        |    ТаблицаАлкогольныхНоменклатур.ТипПродукции,
        |    ТаблицаАлкогольныхНоменклатур.ВидПродукции,
        |    ТаблицаАлкогольныхНоменклатур.Крепость,
        |    ТаблицаАлкогольныхНоменклатур.Производитель,
        |    ТаблицаАлкогольныхНоменклатур.ДатаСреза,
        |    ТаблицаАлкогольныхНоменклатур.Емкость,
        |    ТаблицаАлкогольныхНоменклатур.Сертификат,
        |    ТаблицаАлкогольныхНоменклатур.Импорт,
        |    ТаблицаАлкогольныхНоменклатур.АнализыДляУдостоверенияОКачестве
        |ИЗ
        |    ТаблицаАлкогольныхНоменклатур КАК ТаблицаАлкогольныхНоменклатур";
        ТаблицаАлкогольныхНоменклатур=Запрос.Выполнить().Выгрузить();
        СтруктураОбъектовАлкогольнойПодсистемы.Вставить("ТаблицаАлкогольныхНоменклатур",ТаблицаАлкогольныхНоменклатур);
        СтруктураОбъектовАлкогольнойПодсистемы.Вставить("ТаблицаКомплектовИКомплектующих",ТаблицаКомплектовИКомплектующих);
        ПараметрыСеанса.алкАдресХранилищаОбъектовАлкогольнойПодсистемыПроведения=ПоместитьВоВременноеХранилище(СтруктураОбъектовАлкогольнойПодсистемы,Новый УникальныйИдентификатор());
    Иначе
        Запрос=Новый Запрос;
        Запрос.МенеджерВременныхТаблиц=МенеджерВТ;
        Запрос.Текст=
        "ВЫБРАТЬ
        |    ТаблицаАлкогольныхНоменклатур.ИндексТабличнойЧасти КАК ИндексТабличнойЧасти,
        |    ТаблицаАлкогольныхНоменклатур.НомерСтроки КАК НомерСтроки,
        |    ТаблицаАлкогольныхНоменклатур.Номенклатура КАК Номенклатура,
        |    ТаблицаАлкогольныхНоменклатур.ВидПродукции КАК ВидПродукции,
        |    ТаблицаАлкогольныхНоменклатур.СерияНоменклатуры КАК СерияНоменклатуры,
        |    ТаблицаАлкогольныхНоменклатур.Производитель КАК Производитель,
        |    ТаблицаАлкогольныхНоменклатур.ТипПродукции КАК ТипПродукции,
        |    ТаблицаАлкогольныхНоменклатур.Крепость КАК Крепость,
        |    ТаблицаАлкогольныхНоменклатур.Емкость КАК Емкость,
        |    ТаблицаАлкогольныхНоменклатур.ДатаСреза КАК ДатаСреза,
        |    ТаблицаАлкогольныхНоменклатур.Сертификат,
        |    ТаблицаАлкогольныхНоменклатур.Импорт КАК Импорт,
        |    ТаблицаАлкогольныхНоменклатур.АнализыДляУдостоверенияОКачестве КАК АнализыДляУдостоверенияОКачестве
        |ПОМЕСТИТЬ ТаблицаАлкогольныхНоменклатур
        |ИЗ
        |    ТаблицаАлкогольнойНоменклатуры КАК ТаблицаАлкогольныхНоменклатур
        |
        |ИНДЕКСИРОВАТЬ ПО
        |    Номенклатура";
        Запрос.УстановитьПараметр("ТаблицаАлкогольныхНоменклатур",СтруктураОбъектовАлкогольнойПодсистемы.ТаблицаАлкогольныхНоменклатур);
        Запрос.Выполнить();
    КонецЕсли;
    СтруктураВозврата.Вставить("МенеджерВТ",МенеджерВТ);
    СтруктураВозврата.Вставить("СоответствиеИндексовИИменТЧ",СтруктураОбъектовАлкогольнойПодсистемы.СоответствиеИндексовИИменТЧ);
    СтруктураВозврата.Вставить("СоответствиеИменТЧИИндексов",СтруктураОбъектовАлкогольнойПодсистемы.СоответствиеИменТЧИИндексов);
    СтруктураВозврата.Вставить("ТаблицаАлкогольныхНоменклатур",СтруктураОбъектовАлкогольнойПодсистемы.ТаблицаАлкогольныхНоменклатур);
89 Serginio1
 
29.10.14
15:36
(81) С какого? Будет использован индекс и диапозон по этому индексу.
90 H A D G E H O G s
 
29.10.14
15:37
(89) Если связь будет nestedloops.
91 Гёдза
 
29.10.14
15:37
ГДЕ ХОТЬ ОДИН РЕАЛЬНЫЙ ЗАМЕР????
92 Serginio1
 
29.10.14
15:38
(89) Для интереса сделай временные таблицы проиндексируй и посмотри.
93 H A D G E H O G s
 
29.10.14
15:39
(91) Нету.
94 H A D G E H O G s
 
29.10.14
15:40
(91) Все в разработке.
95 H A D G E H O G s
 
29.10.14
15:40
(91) Расслабься Анатолий, мы тут сначала думаем, а потом прыгаем.
96 H A D G E H O G s
 
29.10.14
15:43
(92) Попробую
97 Ник второй
 
29.10.14
15:52
(96) Только было бы неплохо хеш получать не через соединение строковых представлений ссылок, а через сложение индивидуальных индексов.

Например.
Номенклатура - индекс 5
Характеристика - индекс 2
Серия - индекс 2

в итоге 5+2+2 = 9
ПОнятно что может пересечься со :
Номенклатура - индекс 4
Характеристика - индекс 1
Серия - индекс 4

Но таких совпадений будет малое количество. И Искать действительно по:
Хеш, Номенклатура, Характеристика. Серию исключить, так как при условии совпадения всех трех полей серия определяется точно.
98 H A D G E H O G s
 
29.10.14
15:56
(97) У меня хеш получается не от строковых представлений, а по UUID. Смотрите код внимательным образом.
99 H A D G E H O G s
 
29.10.14
15:58
(97) Что такое
"а через сложение индивидуальных индексов. "
100 Гёдза
 
29.10.14
15:59
(95) если будешь всегда так думать - никогда не поймешь как работает мсскл
101 Ник второй
 
29.10.14
16:00
(98) УИД ты переводишь в строки.
102 Гёдза
 
29.10.14
16:01
Правильный подход: пробовать варианты, смотреть результаты, изучать планы запросов, понимать зависимости
103 H A D G E H O G s
 
29.10.14
16:02
(102) Нечего думать, надо прыгать.
104 H A D G E H O G s
 
29.10.14
16:03
(101) Да. Но в контексте 1С "строковых представлений ссылок" - это наименование/дата-номер для справочников - документов, поэтому не понял тебя.
105 H A D G E H O G s
 
29.10.14
16:03
(103) Это я про подход (102).
106 Гёдза
 
29.10.14
16:07
(103) так никогда экзамен не сдашь
107 H A D G E H O G s
 
29.10.14
16:08
(106) Пофиг.
108 H A D G E H O G s
 
29.10.14
16:11
(106) Чтобы сдать экзамен - надо вызубрить то, что хотят услышать граждане в УЦ, мы тут занимаемся практическими вещами и тут думать надо.
109 Гёдза
 
29.10.14
16:16
(108) как то ты быстро меняешь мнение
(95) > (103) > (108)
110 H A D G E H O G s
 
29.10.14
16:18
(109) см. (105)
111 StaticUnsafe
 
29.10.14
16:33
по-моему эти ребята всех тонко троллят
112 H A D G E H O G s
 
29.10.14
16:35
(92) Не катит.

1C сдвигает поле ХешСвязи в конец при построении индекса, вот так:


Запрос 1С:

        "ВЫБРАТЬ
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.Номенклатура КАК Справочник.Номенклатура) КАК Номенклатура,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.СерияНоменклатуры КАК Справочник.СерииНоменклатуры) КАК СерияНоменклатуры,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.ХарактеристикаНоменклатуры КАК Справочник.ХарактеристикиНоменклатуры) КАК ХарактеристикаНоменклатуры,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.Комплект КАК Справочник.Номенклатура) КАК Комплект,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.СерияКомплекта КАК Справочник.СерииНоменклатуры) КАК СерияКомплекта,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.ХарактеристикаКомплекта КАК Справочник.ХарактеристикиНоменклатуры) КАК ХарактеристикаКомплекта,
        |    ВЫРАЗИТЬ(ТаблицаКомплектовИКомплектующих.ХешСвязи КАК СТРОКА(64)) КАК ХешСвязи
        |ПОМЕСТИТЬ ТаблицаКомплектовИКомплектующих
        |ИЗ
        |    &ТаблицаКомплектовИКомплектующих КАК ТаблицаКомплектовИКомплектующих
        |
        |ИНДЕКСИРОВАТЬ ПО
        |    ХешСвязи,
        |    Комплект,
        |    СерияКомплекта,
        |    ХарактеристикаКомплекта
        |;

Запросы SQL



exec sp_executesql N'INSERT INTO #tt3 (_Q_000_F_000RRef,_Q_000_F_001RRef,_Q_000_F_002RRef,_Q_000_F_003RRef,_Q_000_F_004RRef,_Q_000_F_005RRef,_Q_000_F_006) VALUES(@P1,@P2,@P3,@P4,@P5,@P6,@P7)',N'@P1 varbinary(16),@P2 varbinary(16),@P3 varbinary(16),@P4 varbinary(16),@P5 varbinary(16),@P6 varbinary(16),@P7 nvarchar(max)',0xB89F001D60BEB2E611DDE886D17B1A41,0x00000000000000000000000000000000,0x00000000000000000000000000000000,0xA7E7001CC4BE9A3011E45E90802C0EAD,0xA7E7001CC4BE9A3011E45E915137E73F,0x00000000000000000000000000000000,N'14044659763728896512            


_Q_000_F_006 - хешСвязи, равно 14044659763728896512


create index [TMPIND_1] on [#tt7] (_Q_000_F_003RRef, _Q_000_F_004RRef, _Q_000_F_005RRef, _Q_000_F_006)
113 Ник второй
 
29.10.14
16:37
(99) Что хочешь то и используй, я бы регламентным заданием проставил числовой номер
114 Ник второй
 
29.10.14
16:39
(112) Поменяй местами в запросе индексирование.
115 H A D G E H O G s
 
29.10.14
16:40
(112) Ну и потом 2 вложенных NestedLoops.

Если не пользовать индекс - прекрасный одиночный hashjoin
116 H A D G E H O G s
 
29.10.14
16:42
(114) Монопенисуально.
117 Ник второй
 
29.10.14
16:42
(116) цуки! Я про 1С
118 Ник второй
 
29.10.14
16:43
(117) + Между прочем запиши этот вопрос и задай его Морозову.... интересно что скажет )
119 Ник второй
 
29.10.14
16:44
А вообще в твоем случае создай только один индекс по Хешу, делать индексы по остальным полям бесмысленно в большинстве случаев.
120 H A D G E H O G s
 
29.10.14
16:44
Достаточно любому выполнить в консоле

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    Номенклатура.Наименование,
    Номенклатура.Артикул КАК Артикул
ПОМЕСТИТЬ Товары
ИЗ
    Справочник.Номенклатура КАК Номенклатура

ИНДЕКСИРОВАТЬ ПО
    Артикул,
    Ссылка
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    Товары.Ссылка,
    Товары.Наименование,
    Товары.Артикул
ИЗ
    Товары КАК Товары


и посмотреть Индексы.

Сюрприз, сюрприз
121 H A D G E H O G s
 
29.10.14
16:45
Там еще есть фишечка одна, вообще жесть, но это больше к SQL
122 H A D G E H O G s
 
29.10.14
16:45
(119) Двойной nested loops
123 H A D G E H O G s
 
29.10.14
16:45
(119) Нельзя мне индексы по хешу создавать
124 H A D G E H O G s
 
29.10.14
16:47
(120) С числовыми!!! полями таже куйня.
125 Ник второй
 
29.10.14
16:47
(123) Почему? в должностных инструкциях это прописано.
126 H A D G E H O G s
 
29.10.14
16:47
(124) Я уж подумал, что поле суется в зад индексу, потому что оно черное(зачеркнуто, Строковое)
127 H A D G E H O G s
 
29.10.14
16:48
(125) Ладно, это все лирика, мне лениво.
128 Ник второй
 
29.10.14
16:48
(126) Индекс по строкам это ....... ну ты сам понимаешь, что происходит ..
129 H A D G E H O G s
 
29.10.14
16:49
(128) Ну так и для Числа такая же куйня.
130 Ник второй
 
29.10.14
16:49
(127) надо сувать помидор?
131 Ник второй
 
29.10.14
16:49
(129) Для числа странно... не вижу ограничений.
132 Serginio1
 
29.10.14
17:29
А ты добваь

ВЫБРАТЬ
    Товары.Ссылка,
    Товары.Наименование,
    Товары.Артикул
ИЗ
    Товары КАК Товары
Order By Артикул,
    Ссылка
133 H A D G E H O G s
 
29.10.14
17:37
(132) Куда добавить?
134 Serginio1
 
29.10.14
18:02
(133) в 120
вернее только

Order By Артикул,
    Ссылка

Просто в выборке данных нет смысла в индексации и оптимизатор может выбросить построение индекса
135 H A D G E H O G s
 
29.10.14
18:02
(134) Не выбрасывает :-)
136 Гёдза
 
29.10.14
18:03
(120) ну показывай уже, что там
137 Serginio1
 
29.10.14
18:09
136+ Присоединяюсь
138 H A D G E H O G s
 
29.10.14
18:10
(136) (137) Вот лентяи.

ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    Номенклатура.Наименование,
    Номенклатура.Артикул КАК Артикул
ПОМЕСТИТЬ Товары
ИЗ
    Справочник.Номенклатура КАК Номенклатура

ИНДЕКСИРОВАТЬ ПО
    Артикул,
    Ссылка
;


дает
create index [TMPIND_0] on [#tt1] (_Q_000_F_000RRef, _Q_000_F_002)
139 Гёдза
 
29.10.14
18:11
(138) И ?
140 H A D G E H O G s
 
29.10.14
18:14
(139) Ссылка на первом месте, Артикул на 2-ом
141 Ник второй
 
29.10.14
18:14
(139) Первый индекс по ссылке, а второй по Артиклу.
142 H A D G E H O G s
 
29.10.14
18:15
(141) Индекс один, по 2-м полям.
143 Гёдза
 
29.10.14
18:19
(140) а если 3 поля в индексе?
144 H A D G E H O G s
 
29.10.14
18:19
(143) Примитивные типы (Строка, Число) сдвигаются в конец
145 Serginio1
 
29.10.14
18:20
(138) У меня сейчас нет SQL

create index [TMPIND_0] on [#tt1] (_Q_000_F_000RRef, _Q_000_F_002)

это 1С задает Ты поинтересуйся у них зачем они так делают.
Кстати нельзя указать и Desc
146 Ник второй
 
29.10.14
18:20
(142) не спорю ))) не правильно выразился )
147 Гёдза
 
29.10.14
18:21
(140) говорят это ошибка.
148 Гёдза
 
29.10.14
18:21
149 Гёдза
 
29.10.14
18:21
>>Добрый день. Пытаюсь разобраться с индексами временных таблиц. Насколько я понимаю, при добавлении нескольких полей на закладку индексы создается один индекс по нескольким полям. На этой же закладке можно указать порядок полей в индексе, однако создается впечатление, что платформа игнорирует этот порядок и создает индекс с таким порядком, в котором поля выбираются в запросе.
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой