Имя: Пароль:
1C
1С v8
Кэши разные нужны, кэши нужные важны.
0 H A D G E H O G s
 
20.03.13
16:32
День добрый.
Понял, что заблуждался.
Строка кода
Артикул=Номенклатура.Артикул (1);

создает объектный кэш.
Кэш живет 20 МИНУТ (как оказалось), но через 20 секунд проверяется на валидность считывание поля _version из базы.
http://langslab.com/ebooks/prof-dev2/tome1/pr-dev-t1-ch04

Все нормально, все логично, пока.

Заходим в профайлер и видим, что если мы выполним код (1) ранее чем за 20 секунд - ничего не произойдет, а если после 20 секунд - выполниться 2! запроса:

Первый запрос:

exec sp_executesql N'SELECT
T1._Version
FROM _Reference152 T1
WHERE T1._IDRRef = P1',N'P1 varbinary(16)',0x8041A8E513C95CF74D0C57393F6E2FDB


Второй запрос:

exec sp_executesql N'SELECT
T2._IDRRef,
T2._Version,
T2._Marked,
T2._IsMetadata,
T2._ParentIDRRef,
T2._Folder,
T2._Code,
T2._Description,
T2._Fld2303,
T2._Fld2304RRef,
T2._Fld2305,
T2._Fld2306,
T2._Fld2307,
T2._Fld2308,
T2._Fld2309,
T2._Fld2310,
T2._Fld2311,
T2._Fld2312RRef,
T2._Fld2313RRef,
T2._Fld2314RRef,
T2._Fld2315RRef,
T2._Fld2316,
T2._Fld2317,
T2._Fld2318RRef,
T2._Fld2319,
T2._Fld2320RRef,
T2._Fld2321RRef,
T2._Fld2322RRef,
T2._Fld2323RRef,
T2._Fld2324RRef,
T2._Fld2325RRef,
T2._Fld2326RRef,
T2._Fld2327RRef,
T2._Fld2328RRef,
T2._Fld2329,
T2._Fld2330,
T2._Fld2331,
T2._Fld2332,
T2._Fld2333,
T2._Fld2334RRef,
T2._Fld2335RRef,
T2._Fld2336RRef,
T2._Fld2337RRef,
T2._Fld2339,
T2._Fld2340,
T2._Fld2341RRef,
T2._Fld2342RRef,
T2._Fld2343RRef,
T2._Fld2344RRef,
T2._Fld2345_TYPE,
T2._Fld2345_RTRef,
T2._Fld2345_RRRef,
T2._Fld2346_TYPE,
T2._Fld2346_RTRef,
T2._Fld2346_RRRef,
T2._Fld2347,
T2._Fld2348,
T2._Fld2349,
T2._Fld2350,
T2._Fld2351RRef,
T2._Fld2352RRef,
T2._Fld2353RRef,
T2._Fld2354_TYPE,
T2._Fld2354_S,
T2._Fld2354_RRRef,
T2._Fld2355RRef,
T2._Fld2356RRef,
T2._Fld2357,
T2._Fld2338,
T2._Fld2358RRef,
T2._Fld2359RRef,
T2._Fld2360RRef,
T2._Fld24140RRef,
T2._Fld24141_TYPE,
T2._Fld24141_RTRef,
T2._Fld24141_RRRef,
T2._Fld27221,
T2._Fld27222,
0 AS SDBL_IDENTITY
FROM _Reference152 T2
WHERE T2._IDRRef = P1 AND T2._Version <> @P2',N'P1 varbinary(16),@P2 varbinary(8)',0x8041A8E513C95CF74D0C57393F6E2FDB,0x0000000000E96026


И вот тут то начинаются загадки...
1 sapphire
 
20.03.13
16:35
Дальше, кэп, мы все ждем продолжения
2 H A D G E H O G s
 
20.03.13
16:35
Как я понимаю алгоритм:


Тут либо
1 запрос и если версия изменилась - следом 2 запрос за новыми данными.

либо
2 запрос, который вернет пустую таблицу (если данные непоменялись), либо новые данные.


Но почему сразу 2 запроса?
3 H A D G E H O G s
 
20.03.13
16:35
T2._Version <> @P2 как бы говорит нам, что мы хотим версию, отличную от версии в кэшэ.
4 mikecool
 
20.03.13
16:35
"Кэш живет 20 МИНУТ (как оказалось)" вот чего то я это тоже постоянно упоминаю...
5 H A D G E H O G s
 
20.03.13
16:38
Все становиться веселее, если узнать, что

1) _Version не входит в индексы (хотя для поля timestamp могут быть свои правила, я не знаю).
2) Если в справочнике присутствуют табличные части - выполняется 3 запроса!:

3 запрос:

exec sp_executesql N'SELECT
T3._LineNo2362,
T3._Fld2363_TYPE,
T3._Fld2363_S,
T3._Fld2363_RTRef,
T3._Fld2363_RRRef,
T3._Fld2364_TYPE,
T3._Fld2364_S,
T3._Fld2364_RRRef,
0 AS SDBL_IDENTITY
FROM _Reference152_VT2361 T3
INNER JOIN _Reference152 T4
ON T4._IDRRef = T3._Reference152_IDRRef
WHERE T4._IDRRef = P1 AND T4._Version <> @P2
ORDER BY 9 ASC, T3._LineNo2362',N'P1 varbinary(16),@P2 varbinary(8)',0x8041A8E513C95CF74D0C57393F6E2FDB,0x0000000000E96026


Inner Join шапки с ТЧ.


И все накрывается спелым мехом по производительности.
6 H A D G E H O G s
 
20.03.13
16:39
Вопрос - почему 1С тупо не сравнивает _version и не успокаивается?
7 Serginio1
 
20.03.13
16:39
По уму если ты выполняешь код в транзакции Repeatable read
или Snapshot повторное чтение не имеет смысла.
8 H A D G E H O G s
 
20.03.13
16:43
(7) Не спорю.

Зачем 2-ой запрос при наличии первого?
9 Serginio1
 
20.03.13
16:44
(5) А Зачем на _Version индекс. Ключом является ._IDRRef, а поле _Version сообщает о текущей версии. Версия нужна для разрешения коллизий  например при интерактивном редактировании записи.
10 H A D G E H O G s
 
20.03.13
16:45
Вот такой вот кусок кода дает следующие результаты на прогретом SQL-е


Перем МассивСсылок;



Процедура Тест1Нажатие(Элемент)
   Начало=ТекущаяУниверсальнаяДатаВМиллисекундах();
   Для Каждого Элемент ИЗ МассивСсылок Цикл
       Артикул=Элемент.Артикул;   //Тупо из кэша
   КонецЦикла;
   Конец=ТекущаяУниверсальнаяДатаВМиллисекундах();
   Сообщить("Выполнено за "+Строка(Конец-Начало));
КонецПроцедуры

Процедура Тест2Нажатие(Элемент)
   Начало=ТекущаяУниверсальнаяДатаВМиллисекундах();
   Для Каждого Элемент ИЗ МассивСсылок Цикл
       Артикул=ОбщегоНазначения.ПолучитьЗначениеРеквизита(Элемент,"Артикул");  //Тупо из базы 1 реквизит
   КонецЦикла;
   Конец=ТекущаяУниверсальнаяДатаВМиллисекундах();
   Сообщить("Выполнено за "+Строка(Конец-Начало));
КонецПроцедуры

Процедура Тест3Нажатие(Элемент)
   Начало=ТекущаяУниверсальнаяДатаВМиллисекундах();
   Запрос=Новый Запрос;
   Запрос.Текст=
   "ВЫБРАТЬ
   |    Номенклатура.Ссылка,
   |    Номенклатура.Артикул
   |ИЗ
   |    Справочник.Номенклатура КАК Номенклатура
   |ГДЕ
   |    Номенклатура.Ссылка В(&МассивСсылок)";
   Запрос.УстановитьПараметр("МассивСсылок",МассивСсылок);
   Выборка=Запрос.Выполнить().Выбрать();
   
   Пока Выборка.Следующий() Цикл
       Артикул=Выборка.Артикул;    //Тупо из базы 1 реквизит но за 1 запрос
   КонецЦикла;
   Конец=ТекущаяУниверсальнаяДатаВМиллисекундах();
   Сообщить("Выполнено за "+Строка(Конец-Начало));
КонецПроцедуры

Процедура ПодготовитьНажатие(Элемент)
   Запрос=Новый Запрос;
   Запрос.Текст=
   "ВЫБРАТЬ ПЕРВЫЕ 1000
   |    Номенклатура.Ссылка КАК Ссылка
   |ИЗ
   |    Справочник.Номенклатура КАК Номенклатура
   |ГДЕ
   |    Номенклатура.ЭтоГруппа = ЛОЖЬ";
   МассивСсылок=Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"); //Готовим массив ссылок
   Для Каждого Элемент ИЗ МассивСсылок Цикл
       Артикул=Элемент.Артикул;   //Читаем в кэш
   КонецЦикла;
КонецПроцедуры



тест1: Выполнено за 14 708
тест2: Выполнено за 3 398
тест3: Выполнено за 130
11 Лефмихалыч
 
20.03.13
16:46
я не понял, так кто в итоге всех убил-то?
12 H A D G E H O G s
 
20.03.13
16:46
(9) Счаст план запроса гляну на 2 запрос.
13 H A D G E H O G s
 
20.03.13
16:47
(11) Ежи - каннибалы.
14 acsent
 
20.03.13
16:47
(8) может кэш устарел?
15 Fragster
 
гуру
20.03.13
16:47
так ведь не зря 1с рекомендует юзать запросы
16 Fragster
 
гуру
20.03.13
16:48
тем более, что тест3 должен быть запросом в цикле
17 Fragster
 
гуру
20.03.13
16:48
по 1 элементу
18 Fragster
 
гуру
20.03.13
16:48
а, это тест 2
19 H A D G E H O G s
 
20.03.13
16:50
(14) 20 минут точно не прошло.
20 H A D G E H O G s
 
20.03.13
16:51
Единственная мысль - память не хватает на сервере 1С, вот он кэш и вырезает, сервер боевой
21 H A D G E H O G s
 
20.03.13
16:52
кто - нибудь, может глянуть у себя, 8.2.17.157.
22 Конфигуратор1с
 
20.03.13
16:53
(0) "Кэш живет 20 МИНУТ (как оказалось)," могу заблуждаться. но это еще в 8.0 писалось в книжках умных о том , что кэш живет двадцать минут
23 acsent
 
20.03.13
16:54
20 мин максимум
24 Лефмихалыч
 
20.03.13
16:54
(21) чо тебе это даст? Хочешь вывести 1С на чистую воду?
25 Конфигуратор1с
 
20.03.13
16:54
(20) кстати. об этом тоже вродеписалось, что 20 минут он живет если память не переполняется.
26 Serginio1
 
20.03.13
16:55
Для интереса проверь два прохода в транзакции. Первый запрос не нужен, достаточно одного второго.
27 H A D G E H O G s
 
20.03.13
16:55
(24) Понять и простить.
28 H A D G E H O G s
 
20.03.13
16:56
Мне все понятно насчет кэша, у меня простой вопрос - зачем 1С делает 2 запрос при наличии первого?
29 sapphire
 
20.03.13
16:58
(21) Когда получаешь объектные данные, то 1С тянет весь объект целиком. Со всеми табличными частями и прочим.

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

Можно посмотреть трассировкой при выполнении кода.
30 Конфигуратор1с
 
20.03.13
16:58
http://langslab.com/ebooks/prof-dev2/tome1/pr-dev-t1-ch04


Считанные данные будут находиться в кеше до тех пор, пока не наступит одно из четырех событий:

? считанные данные будут вытеснены из кеша другими считанными данными других объектов (переполнение кеша);

? при очередном обращении к кешу окажется, что считанные данные были изменены в базе данных;

? закончится интервал времени в 20 минут;

? данные будут изменены в базе данных.

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

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

Если обращение происходит в пределах 20 секунд после поступления данных в кеш, данные считаются верными (валидными). Если интервал превысил 20 секунд, будет выполняться проверка на то, что версия данных, хранящихся в кеше, соответствует версии данных, находящихся в базе данных. Если окажется, что версии данных не совпадают (т. е. произошло изменение данных в базе данных), данные, находящиеся в кеше, будут удалены из него и выполнено повторное считывание данных из базы данных. Начиная с этого момента, начнется отсчет следующего
20-секундного интервала валидности этих данных.
31 Serginio1
 
20.03.13
16:59
(28) Если версии изменены то нужен второй запрос. Только по уму первый запрос не нужен.
32 H A D G E H O G s
 
20.03.13
17:00
(29) Это понятно как божий день.
33 sapphire
 
20.03.13
17:00
(28) Опрашивает БД на предмет измененности объекта.
34 H A D G E H O G s
 
20.03.13
17:00
(31) Версии не изменены.
Зачем делается 2 запрос?
35 Конфигуратор1с
 
20.03.13
17:00
я так понимаю ответ здесь
Если обращение происходит в пределах 20 секунд после поступления данных в кеш, данные считаются верными (валидными). Если интервал превысил 20 секунд, будет выполняться проверка на то, что версия данных, хранящихся в кеше, соответствует версии данных, находящихся в базе данных. Если окажется, что версии данных не совпадают (т. е. произошло изменение данных в базе данных), данные, находящиеся в кеше, будут удалены из него и выполнено повторное считывание данных из базы данных. Начиная с этого момента, начнется отсчет следующего
20-секундного интервала валидности этих данных.
36 H A D G E H O G s
 
20.03.13
17:00
(33) Это делает первый запрос.
37 H A D G E H O G s
 
20.03.13
17:01
Почти уверен, что 2 запрос возвращает 0 строк.
38 sapphire
 
20.03.13
17:02
(31) Не совсем так, если первый не вернет ничего, то второго запроса не будет. Т.е. логика примерно такая - проверить надо ли что либо возвращать, еслит да то верни всё.
39 H A D G E H O G s
 
20.03.13
17:02
Да, 2 запрос возвращает 0 строк.
40 sapphire
 
20.03.13
17:03
(39) Это говорит о том, что объект не изменился.
41 H A D G E H O G s
 
20.03.13
17:04
(40) О том, что объект не изменился - должен говорить 1-ый запрос, либо 1-ого запроса вообще не должно быть.

Где я не прав?
42 acsent
 
20.03.13
17:05
на партнерке спрашивал?
43 H A D G E H O G s
 
20.03.13
17:06
(42) Я думаю, что справимся своими силами.
44 Лефмихалыч
 
20.03.13
17:06
(41) ну это ж классика, чо ты, как маленький

if some_var
{
  //...
}else
{
  if !some_var // на всякий случай
   {}
}
45 sapphire
 
20.03.13
17:07
(41) Нет, они так сделали изначально, что версия ссылки на объект в памяти не хранится. Иначе зачем метод получения версии у объекта?
46 Serginio1
 
20.03.13
17:08
(20) Если смотреть на устройства "объекта", то есть 2 вида устройства кэша .Объект имеет поля и свойства. Если поле не заполнено, то вызывается запрос. А вот сброс заполнения полей маловероятно. Второе есть кэш объектов в виде хэш таблицы и при доступе через свойство данные считываются из него. По уму кэши должны сбрасываться, по самому позднему скачиванию данных.
47 H A D G E H O G s
 
20.03.13
17:09
(45) Не вижу здравого смысла в твоих словах.
48 H A D G E H O G s
 
20.03.13
17:09
(46) Я нифига не понял!
49 Лефмихалыч
 
20.03.13
17:09
(45) а дак, а, если версия в памяти не хранится, как тогда понять, что объект не изменился?
50 Serginio1
 
20.03.13
17:11
(45) А зачем тащить версию во втором запросе?
T2._IDRRef,
T2._Version,
51 Лефмихалыч
 
20.03.13
17:11
+ (49) и метод там скорее всего, чтобы гарантировать неизменность поля _Version  в объекте, а не чтобы запрос из метода выполнять
52 acsent
 
20.03.13
17:11
(49) хранить версию в памяти бессмысленно, так объект всегда будет актуален
53 sapphire
 
20.03.13
17:12
(49) при обращении к ссылке как раз и возникают запросы, как в (0)
54 sapphire
 
20.03.13
17:13
(52) Сам объект в памяти не хранится и не кешируется :)
Это слишком затратно.
55 Serginio1
 
20.03.13
17:13
(45) Первым запросом мы можем получить версию отличную от текущей и нет смысла её подставлять во второй запрос.
56 H A D G E H O G s
 
20.03.13
17:13
Чето парни вас не туда понесло.
57 sapphire
 
20.03.13
17:14
(51)  >>чтобы гарантировать неизменность поля _Version  в объекте, а не чтобы запрос из метода выполнять

Неверно.
58 sapphire
 
20.03.13
17:14
(56) Ну как ты в (0) начал так и понесло :)
59 Serginio1
 
20.03.13
17:18
(54) Кэш сам по сути вещь затратная, но упрощает создание кода. Хранить в кэше можно не все поля а только те которые вызываются, но судя по второму запросу считывается объект полностью.
60 Asmody
 
20.03.13
17:18
в (0) Номенклатура это объект или ссылка?
61 acsent
 
20.03.13
17:19
(60) судя по тестам ссылка
62 H A D G E H O G s
 
20.03.13
17:20
(60) Ссылка.
63 H A D G E H O G s
 
20.03.13
17:21
(59) КОНЕЧНО. Об это знает практически любой.
64 H A D G E H O G s
 
20.03.13
17:23
Попробуйте открыть в 2-х сеансах 1 элемент справочника, во 2 сеансе измените и запишите его, а потом поменяйте наименование в 1 сеансе, увидьте
"Данные были изменены или удалены" и запрос в SQL:

exec sp_executesql N'SELECT
T1._Version
FROM _Reference13 T1 WITH(NOLOCK)
WHERE T1._IDRRef = P1',N'P1 varbinary(16)',0xA5FD001CC4BE9A3011E29148F9DACD38

и скажите, что версия не храниться в памяти.
65 sapphire
 
20.03.13
17:24
(59) Так и есть
66 acsent
 
20.03.13
17:24
(64) конечно храниться иначе как ее можно будет проверить на актуальность
67 sapphire
 
20.03.13
17:26
(64) Не хранится версия в памяти.
Просто при комите транзакции используется оповещение рефереров   для конкретной ссылки.
68 sapphire
 
20.03.13
17:26
(66) Хочешь, проверь. Хранится, или нет.
69 acsent
 
20.03.13
17:28
Отуда тогда берется это 0xA5FD001CC4BE9A3011E29148F9DACD38
70 ДенисЧ
 
20.03.13
17:28
(69) А если запрос прочитаь? :-)
71 H A D G E H O G s
 
20.03.13
17:30
(69) Это _IDRRef , Анатолий...

Вот, он вытаскивает _Version, сравнивает с тем, что у него в памяти сервера 1С на открытый объект и при разных значениях - выводит "данные изменены".

Все просто.
72 H A D G E H O G s
 
20.03.13
17:32
(67)
"Просто при комите транзакции используется оповещение рефереров   для конкретной ссылки."

Вас, граждане мудрецы в башнях из слоновой кости

МихаилМ
Serginio1
sapphire

надо огораживать в отдельную группу абсолютно умных и невероятно бесполезных граждан.
73 acsent
 
20.03.13
17:32
(71) эх совсем старый стал (((
74 Serginio1
 
20.03.13
17:33
(67) Кластеров может быть не один. И оповещать различные кластера тоже не менее затратная.
75 Serginio1
 
20.03.13
17:34
(72) Я для себя уточняю устройство кэша в 1С.
76 H A D G E H O G s
 
20.03.13
17:37
(75) Да я не против. Просто надо уменьшать уровень абстракции в общении, особенно не личном.
77 Serginio1
 
20.03.13
17:43
(76) Ну в общем я уже давно высказался, что первый запрос не имеет смысла. Другое дело, что использовать кэш имеет смысл в транзакции. А 20 минут период большой и получить косяк из за кэша нет большого смысла.
78 sapphire
 
20.03.13
17:45
(77) Имеет смысл, как раз для массивов и другой программной хрени, куда может входить объект.
79 sapphire
 
20.03.13
17:45
(76) Если лезешь в потроха платформы, то должен представлять примерно как это работает.
81 sapphire
 
20.03.13
17:46
(80) :)
83 H A D G E H O G s
 
20.03.13
17:48
(79) Ну давай, расскажи, что делает 1 запрос.
84 Serginio1
 
20.03.13
17:57
(78) По уму не имеет. Там где действительно нужен кэш, его легче организовать самому с минимальным набором необходимых полей и с запросом не по каждой ссылке а скопом. Так из-за одного артикула вторым запросом скачивается весь объект.
А вот транзакционный кэш имеет бОльший смысл, т.к. хранится минимум времени только на этапе транзакции.
85 Sammo
 
20.03.13
18:13
Чтото мне имхается, что если первый скулевский запрос возвращает что-либо, то второго не будет (точнее не должно быть)
86 sapphire
 
20.03.13
18:18
(85) О том и речь
87 Serginio1
 
20.03.13
18:35
(85) См 39
88 H A D G E H O G s
 
20.03.13
19:05
(85) Фух, ну наконец-то.
89 Эстет хренов
 
20.03.13
20:42
(0) мда, 1с до нормального lazy load як до неба рачки.
90 H A D G E H O G s
 
20.03.13
20:43
(89) Че сказать то хотел?
91 acsent
 
20.03.13
20:47
(89) почему же. Движения документа например не считываются сразу
92 acsent
 
20.03.13
20:49
делать ленивую оптимизацию по каждому полю отдельно - невыгодно.
хотя вот если бы тч атвоматом не читались было бы лучше
93 Эстет хренов
 
20.03.13
20:59
(90) да я про тоже
(91) по сути, движения это другой объект
(92) согласен,имхо, чтение ТЧ объекта самое тяжелое, можно было поставить заглушку, и подгружать при первом обращении.
94 Serginio1
 
21.03.13
11:38
(85) Ну первый то запрос по любому возвращает _Version
95 Odavid
 
29.03.13
12:02
(41)>>О том, что объект не изменился - должен говорить 1-ый запрос, либо 1-ого запроса вообще не должно быть.
Не совсем так, получается.
Похоже, ответ такой:
1С ВСЕГДА берет полное соединение таблиц и вытягивает все данные (как и сказано в (_29)) - и после этого помещает их в кэш.
Далее, идет работа с кэшем и, собственно, сам вопрос ТС.
Первый запрос (в течении 20 секунд) - 1С считает данные однозначно валидными, и берет их из кэша - без проверки версии (получает только версию из базы - и уже по ней данные из кэша).
"Если обращение происходит в пределах 20 секунд после поступления данных в кеш, данные считаются верными (валидными)."
После 20 сек - данные в кэше уже НЕ СЧИТАЮТСЯ валидными, т.е, считаются ВОЗМОЖНО измененными в базе, поэтому они получаются заново ЦЕЛИКОМ для сравнения версии.
Версия не изменилась - берет снова из кэша данные (и так в течении 20 минут).
Версия изменилась - берет вновь полученные данные из базы, пишет в кэш, начинает отсчет следующих 20 минут.
("при очередном обращении к кешу окажется, что считанные данные были изменены в базе данных;").
Т.е.:
- данные ВСЕГДА первоначально выбираются все связанные (из базы).
- данные при любом раскладе проходят через кэш 1С.
- кэш "отрабатывает" только в течении первых 20 секунд ("безусловно"), потом - дает прирост, только если получение данных 1С-сервером из "своего" кэша быстрее, чем заново считанных.
Таким образом, 1С не ориентирована на кэширование "часто испоользуемых" данных и "интеллектуальную" выборку из кэша "только необходимого (отрабатывает полную выборку и только потом - сравнение версий)), + не рассчитана на обработку больших объемов данных (берет все данные из связанных таблицы из базы для обработки и отсеивания "ненужного" на 1С-сервере).
96 Odavid
 
29.03.13
12:05
(85) первый запрос отрабатывает только для получения версии и БЕЗУСЛОВНОГО посика по ней данных в кэше.
Т.е. 1С уверена на вссе 100, что данные не менялись в течении 20 секунд + они однозначно есть в кэше.
А вот второй уже и делает ту самую проверку на валидность (сравнение версий), и далее отрабатывает два варианта из (_95).
97 H A D G E H O G s
 
29.03.13
12:11
(95) Бред какой-то
98 H A D G E H O G s
 
29.03.13
12:12
После 20 сек - данные в кэше уже НЕ СЧИТАЮТСЯ валидными, т.е, считаются ВОЗМОЖНО измененными в базе, поэтому они получаются заново ЦЕЛИКОМ для сравнения версии.


Смысл кэша после 20 секунд?
99 Odavid
 
29.03.13
12:13
(67)>>Просто при комите транзакции используется оповещение рефереров   для конкретной ссылки.
согласен.
Отсюда и кажущаяся "быстрота" обработки и "отсутствие" запроса по базе.
"Запрос" в данном случае есть, только не по базе, а по "1С-серверу" (кэшу там своему или еще чего они туда вмудрили для этого), там же и ссылка на объект хранится.
100 Odavid
 
29.03.13
12:14
(97) бред - это ты пишешь уже на 100 потсов почти :)
но никак не поймешь смысл :)
101 Odavid
 
29.03.13
12:16
>>Смысл кэша после 20 секунд?
я уже написал смысл.
По большому счету - смысла в кэше 1С нет, что и подтверждается тормозами при обработке больших объемов данных :)
А также - жестким ограничением "кэша" внутри 1С, иначен, в противном случае его "нормального" пользования - был бы хотя бы диапазон регулирвоания размера.
102 H A D G E H O G s
 
29.03.13
12:17
(101) Тормоза при обработке больших объемов данных - это

"Запрос в цикле" для всех полей справочника.

Только и всего.
103 H A D G E H O G s
 
29.03.13
12:18
(101) Про смысл ты нифига не написал.
104 Odavid
 
29.03.13
12:20
(102) тормоза - это тормоза.
А не цикл обработки полей справочника.
Тормоза - это когда 1С получает сотни тысяч записей, и пытается их обработать.
Жаль, что вы даже не знаете, как происходит обработка данных в СУБД (даже не 1С).
105 Odavid
 
29.03.13
12:21
Смысл такой (постор):
"Версия не изменилась - берет снова из кэша данные (и так в течении 20 минут).
Версия изменилась - берет вновь полученные данные из базы, пишет в кэш, начинает отсчет следующих 20 минут."
106 Odavid
 
29.03.13
12:21
*повтор
107 Odavid
 
29.03.13
12:22
и еще -
"По большому счету - смысла в кэше 1С нет"
т.к. в любом случае либо берутся "валидные" данные в течении 20 сек, либо - берутся из базы, сравниваются с "кэшовыми", и только потом - принимается решение, что делать дальше.
108 Odavid
 
29.03.13
12:23
(103) ваши "тесты"-запросы это подтверждают однозначно. Как и профайлер SQL.
Почему Вам непонятно - не ясно :)))
109 Axel2009
 
29.03.13
12:26
(10) на счет теста 3, я бы рекоммендовал залить массив во временную таблицу и через джоин выбирать данные. а то ненароком весь поиск по индексу может свалиться в скан индекса, при более менее большом массиве.
110 H A D G E H O G s
 
29.03.13
12:27
(104) Да уж, куда нам, убогим.
111 H A D G E H O G s
 
29.03.13
12:28
(105)

"Версия изменилась - берет вновь полученные данные из базы, пишет в кэш, начинает отсчет следующих 20 минут."

От оно че, Михалыч..


А если версия не изменилась?
112 H A D G E H O G s
 
29.03.13
12:29
(107) Вы нихера не понимаете смысл кэша штоле?
113 Odavid
 
29.03.13
12:29
(109)>>а то ненароком весь поиск по индексу
у нас главный вопрос - зачем при "настоящем" кэше два практически взаимоисключающих запроса в течении периода "жизни" кэша.
114 Axel2009
 
29.03.13
12:30
(0) в целом по кэшам
сколько ни игрался с выборкой данных через точку, ниразу не получалось боле менее быстро, значит данные не хранятся в кэше и они запрашиваются постоянно в базульку. поэтому надеяться на кэш я бы не стал, даже если пишут про всякие 20 минут.

иначе выборка друг за дружкой одних и тех же данных занимала от 15 секунд, до 130 мили секунд (нет обращений к СУБД). а такого я ни разу не видел, даже на статичных данных..
115 H A D G E H O G s
 
29.03.13
12:30
(113) Ты же ответил на этот вопрос в (95), не?
116 Odavid
 
29.03.13
12:31
(112) это вы нихера не понимаете 1С и обработку данных.
И кэш тоже.
Не важно, какой смысл в кэше, и как он реализован в СУБД, важно - что реализовано на самом деле в 1С.
117 H A D G E H O G s
 
29.03.13
12:31
(114) Ну первые 20 секунд у нас быстрых есть :-)
118 Odavid
 
29.03.13
12:32
(115) да, я-то ответил, но народ (и вы) - в неведении :)
И задают смежные вопросы.
119 Odavid
 
29.03.13
12:33
(117) это верно :)
Только вот 1С не позаботилась, что в течении 20 сек - данные могут все-таки меняться...
120 H A D G E H O G s
 
29.03.13
12:33
(118) Ты нихера не ответил.
121 Odavid
 
29.03.13
12:37
(120) вы просто не хотите читать.
А хотите верить и дальше, что 1С - великая сситема.
А не набор поделок на коленке.
Вы хотите получить ответ, совмещающий как реализацию кэша (как области хранения и быстрой выборки часто используемых данных), так и прямо противоположные этому результаты работы 1С-севрера (и данные профайлера), которые видите перед собой.
А так НИКОГДА НЕ ПОЛУЧИТСЯ.
Нужно чем-то поступиться - либо определение кэша сместить в "понятия 1С", либо - признать, что ошибался всю сознательную деятельность работы с 1С :)))
122 H A D G E H O G s
 
29.03.13
12:38
(121) Иди, убей себя ап стену, балаболка.
123 Odavid
 
29.03.13
12:40
(114)>>значит данные не хранятся в кэше и они запрашиваются постоянно в базульку
- именно это и подтверждается всеми данными, в том числе - выкладками    H A D G E H O G s.
Но очень трудно признаться себе в том, что тебя нагло и беспринципнро обманывали долгое время, а ты еще и радовался этому :)
124 Odavid
 
29.03.13
12:40
(122) это ты балаболка.
бестолковая :)
125 Odavid
 
29.03.13
12:41
получить данные и не суметь их объяснить - хуже, чем не получить.
Т.юе. ты не понимаешь вообще, что с чем и как работает.
Правда, в среде 1с это поощряется даже, и в не последнюю очередь - чтобы вот такими вопросами, как эта тема, не задавались.
126 Odavid
 
29.03.13
12:42
(122) вижу, ты уже убился.. бедняжка..
стена-то хоть не пострадала? :)
127 Odavid
 
29.03.13
12:48
(111)>>А если версия не изменилась?
- уже написано:
"Версия не изменилась - берет снова из кэша данные (и так в течении 20 минут)."
т.е. УЖЕ после того, как получены данные (второй запрос), сравнены версии, и выявлено, что версия не менялась.
"...потом - дает прирост, только если получение данных 1С-сервером из "своего" кэша быстрее, чем заново считанных."
Вы просто не хотите (или уже не умеете? ;) ) читать.
128 Odavid
 
29.03.13
12:55
+( 127) т.е., грубо говоря, данные кэша - хранятся в одной области памяти (диске), данные вновь полученной выборки для валидации (второй запрос) - в другой области.
И если 1С серверу "удобнее" и быстрее получить эти данные из "области" кэша - то прирост будет.
Если нет - прироста не будет.
ЧТо и подтверждено многочисленными практическими наблюдениями (прироста нет после 20 сек, т.к. обе "области" - примерно "равнодоступные" для сервера по быстродействию железа)
129 H A D G E H O G s
 
29.03.13
12:55
(128) Все, иди лесом, дятелъ.
130 Odavid
 
29.03.13
12:56
++ это и есть "понимание кэша" по 1С, если кто еще не понял :)
131 Odavid
 
29.03.13
12:56
(129) лесом уже ты пошел.
С поста так 10-го :)
И чем дальше - тем больше дров наломал.
132 Odavid
 
29.03.13
12:58
>>Все, иди лесом, дятелъ.
- чем бы 1сник не тешился - лишь бы не терял веры в 1С! :)
ну, и перейти на ругань - первейшее дело для 1сника.
133 H A D G E H O G s
 
29.03.13
13:00
(128) Чтобы ты немножко задумался зайчатками своего мозга - размер выборки второго запроса =0.
134 Зойч
 
29.03.13
13:03
Ребята, давайте жить дружно!
136 H A D G E H O G s
 
29.03.13
13:07
А про быструю и медленную часть сервера 1С - порадовало. Давненько такого не было.
138 Odavid
 
29.03.13
13:34
(136)>>А про быструю и медленную часть сервера 1С - порадовало
ну, а что еще тебя может порадовать - не поиск же ответа :)
Так, одна радость - себя показать, других посмотреть. Авось кто приметит....
139 Odavid
 
29.03.13
13:35
(135) ты "одинаково дружно" не дружишь даже сам с собой :)
140 H A D G E H O G s
 
29.03.13
13:37
(137) Конечно есть, если судить по (128):

грубо говоря, данные кэша - хранятся в одной области памяти (диске), данные вновь полученной выборки для валидации (второй запрос) - в другой области.
И если 1С серверу "удобнее" и быстрее получить эти данные из "области" кэша - то прирост будет.
Если нет - прироста не будет.


А если выполнить запрос в (0) - нет.
141 TormozIT
 
гуру
29.03.13
15:21
Внесу свои 5 копеек.
Исследование объектного кэширования считаю корректно проводить при следующих условиях
- в клиент-серверном варианте установив монопольный режим
- закрыты все формы, в которых может использоваться объектный кэш (отображаются ссылочные данные)
- с момента завершения предыдущего запуска прошло не менее 20 сек
- общая длительность теста для упрощения условия не должна превышать 20 сек

Я провел такой замер кодом

Сообщить(ТекущаяДата());
Количество = 1000;
ИмяСправочникаБезГрупп = Метаданные.Справочники.СвойстваМетаданных2iS.Имя;
ИмяПоля = "ПометкаУдаления";
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ " + XMLСтрока(Количество) + "
|    Т.Ссылка
|ИЗ
|    Справочник." + ИмяСправочникаБезГрупп + " КАК Т";
МассивСсылок = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"); //Готовим массив ссылок
Количество = МассивСсылок.Количество();
Сообщить("Размер выборки " + Количество);
УФ(сНачатьЗамер, Количество, "Подготовка объектного кэша");
Для Каждого Элемент ИЗ МассивСсылок Цикл
   Пустышка = Элемент[ИмяПоля];
КонецЦикла;
УФ(сЗакончитьЗамер);

УФ(сНачатьЗамер, Количество, "Чтение с использованием объектного кэширования");
Для Каждого Элемент ИЗ МассивСсылок Цикл
   Пустышка = Элемент[ИмяПоля];
КонецЦикла;
УФ(сЗакончитьЗамер);

УФ(сНачатьЗамер, Количество, "Чтение отдельными запросами");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Т.Ссылка,
|    Т." + ИмяПоля + "
|ИЗ
|    Справочник." + ИмяСправочникаБезГрупп + " КАК Т
|ГДЕ
|    Т.Ссылка = &Ссылка";
Для Каждого Элемент ИЗ МассивСсылок Цикл
   Запрос.УстановитьПараметр("Ссылка", Элемент);
   Пустыщка = Запрос.Выполнить().Выгрузить()[0][ИмяПоля];
КонецЦикла;
УФ(сЗакончитьЗамер);

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Т.Ссылка,
|    Т." + ИмяПоля + "
|ИЗ
|    Справочник." + ИмяСправочникаБезГрупп + " КАК Т
|ГДЕ
|    Т.Ссылка В(&МассивСсылок)";
Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
УФ(сНачатьЗамер, Количество, "Чтение общим запросом");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
   Пустыщка = Выборка[ИмяПоля];
КонецЦикла;
УФ(сЗакончитьЗамер);

И получил ожидаемый результат

Окончание замера "Подготовка объектного кэша" - Длительность = 8,144 с, Среднее = 0,008144 с
Окончание замера "Чтение с использованием объектного кэширования" - Длительность =  0с, Среднее =  0с
Окончание замера "Чтение отдельными запросами" - Длительность = 2,106 с, Среднее = 0,002106 с
Окончание замера "Чтение общим запросом" - Длительность = 0,078 с, Среднее = 0,000078 с
142 Serginio1
 
29.03.13
16:24
(141) Вообще то есть транзакционный кэш. Практика грязного чтения весьма порочна.
143 H A D G E H O G s
 
29.03.13
16:34
Замени

МассивСсылок = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"); //Готовим массив ссылок

на

МассивСсылок = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"); //Готовим массив ссылок

СходитьПокуритьВСекундах(22);
144 TormozIT
 
гуру
29.03.13
16:43
(143) Цитирую себя же из (141) "- общая длительность теста для упрощения условия не должна превышать 20 сек "
В предлагаемом варианте объектный кэш будет целиком перепроверен (количество обращений к серверу по идее будет таким же, как и при его заполнении).

Вот результаты

Окончание замера "Подготовка объектного кэша" - Длительность = 8.018 с, Среднее = 0.008018 с
Окончание замера "Чтение с использованием объектного кэширования до 20сек" - Длительность = 0.016 с, Среднее = 0.000016 с
Окончание замера "Чтение с использованием объектного кэширования после 20сек" - Длительность = 7.441 с, Среднее = 0.007441 с
Окончание замера "Чтение отдельными запросами" - Длительность = 2.215 с, Среднее = 0.002215 с
Окончание замера "Чтение общим запросом" - Длительность = 0.078 с, Среднее = 0.000078 с

Видно, что проверка актуальности данных объектного кэша лишь немногим быстрее чтения объекта в кэш.
145 H A D G E H O G s
 
29.03.13
16:53
(144) "лишь немногим быстрее чтения объекта в кэш."

Почти уверен, что справочник содержит ТЧ.
146 H A D G E H O G s
 
29.03.13
16:54
Если ТЧ не будет - разрыв будет существенней.
147 TormozIT
 
гуру
29.03.13
16:58
(145) Да, справочник был с ТЧ.
А вот почти та же картина на справочнике без ТЧ

Окончание замера "Подготовка объектного кэша" - Длительность = 6.988 с, Среднее = 0.006988 с
Окончание замера "Чтение с использованием объектного кэширования до 20сек" - Длительность = 0.016 с, Среднее = 0.000016 с
Окончание замера "Чтение с использованием объектного кэширования после 20сек" - Длительность = 6.77 с, Среднее = 0.00677 с
Окончание замера "Чтение отдельными запросами" - Длительность = 2.34 с, Среднее = 0.00234 с
Окончание замера "Чтение общим запросом" - Длительность = 0.078 с, Среднее = 0.000078 с
148 H A D G E H O G s
 
29.03.13
16:58
Воопщем, мне все понятно. Что ничего не понятно, зачем они так сделали.

И почему после 20 секунд выполняется попытка тащить с SQL обновленных данных, даже если их нет. А их нет, так как версия не изменилась. Но на innerjoin с ТЧ надо потратиться время.

А разница в 8.018сек- 7.441 с возникает из-за того, что
при 8.018сек - выборка не пуста, а при 7.441 - пуста.
149 H A D G E H O G s
 
29.03.13
17:00
(147) Значит я был не прав насчет InnerJoin
150 Serginio1
 
29.03.13
17:05
(147) Добавь время запроа на выборку несуществющих элементов. Например список кодов которых нет в базе. Тогда посмотрим сколько времения занимает второй запрос
151 H A D G E H O G s
 
29.03.13
17:07
(150) А это зачем?
152 TormozIT
 
гуру
29.03.13
17:08
Думаю чтение версии отдельно и всего объекта выполняются вместе, чтобы не делать новый запрос к серверу СУБД в случае если версия изменилась.

Предполагаю что алгоритм примерно такой, если прошло 20 сек
1. Строим запрос для чтения версии
2. Строим запрос для чтения объекта
3. Склеиваем 1+2 в пакет
4. Отправляем запрос в СУБД
5. Получаем результат пакета из СУБД
6. Если версия из результата запроса 1 не совпадает с версией в кэше, то берем результат запроса 2 и помещаем (обновляем) его в кэш.
7. Возвращаем объект из кэша.
153 Serginio1
 
29.03.13
17:08
Вернее не код а любой атрибут без индекса
эмуляция
Select * From T2
WHERE T2._IDRRef = P1 AND T2._Version <> @P2
154 H A D G E H O G s
 
29.03.13
17:08
(152) Но это же дикость!
155 H A D G E H O G s
 
29.03.13
17:09
(153) Понял.
156 Serginio1
 
29.03.13
17:10
(151) Ну у тебя то в итоге получается 2 запроса.
вот Чтение отдельными запросами это тогда когда запись изменена.
157 H A D G E H O G s
 
29.03.13
17:12
(156) И тогда, когда не изменена - тоже 2 запроса.
158 TormozIT
 
гуру
29.03.13
17:14
(154) Алгоритм в 152 я предложил, основываясь на твоих наблюдениях в (0). Сам пока не проверял. Возможно ты провел не очень чистый эксперимент. Действительно такой алгоритм кажется неоптимальным, т.к. изменения данных происходят гораздо реже, чем чтение.
159 Serginio1
 
29.03.13
17:15
(157) Я про то , что тест тянет все записи, а в реалии они не тянутся

Кста ответь на вопрос из v8: Чудеса с индексами.
что дает условие на равество =4.7 для SQL варианта.
В файловой версии возвращает 5. Там ясно что приведение через cast к Число.
А вот если в SQL вернет 4, то значит индексы хранятся ввиде int и приводятся к ште
160 H A D G E H O G s
 
29.03.13
17:16
(153) WHERE T2._IDRRef = P1 AND T2._Version <> @P2


Все равно делает поиск по кластерному индексу.
161 H A D G E H O G s
 
29.03.13
17:17
(159) 1С зарегало ошибку платформы на партнерском :-)
162 Serginio1
 
29.03.13
17:18
(160) Это понятно. Но одно дело вернуть данные потом их обработать на сервере или ничего не возвращать.
163 H A D G E H O G s
 
29.03.13
17:18
Надо попробовать 18 релиз поставить, нуавдруг.
164 Sammo
 
29.03.13
17:18
(158) Может и поломалось что-то. Как вариант - задать вопрос на партнерском - у кого есть доступ
165 H A D G E H O G s
 
29.03.13
17:18
(162) Вооот! Именно про это я говорил в (148)
166 Aprobator
 
29.03.13
17:19
может вся бодяга из за обращений клиента к серверу? Типа 1С сразу формирует и то и то, чтобы случ чего 2 раза на сервер не бегать?
167 Serginio1
 
29.03.13
17:19
(160) Так что SQL то возвращает или как оно и должно ничего не возвращает ?
168 H A D G E H O G s
 
29.03.13
17:22
(167) Оно не должно делать 2 запрос вообще.


Tormozit, будь добр, закинь в тест запрос по 1 полю:

ВерсияДанных
169 Serginio1
 
29.03.13
17:23
(165) На самом деле не все ясно, так как при подготовке кэша не нужно делать 2 х запросов, так как данных просто нет и нужно делать только один запрос. Просто в 1С могут и при этом сделать 2 запроса.
170 H A D G E H O G s
 
29.03.13
17:23
Надо ставить 18 релиз короче.
Этим я и займусь счаст.
171 Serginio1
 
29.03.13
17:24
(167) Это я прекрасно понимаю. Достаточно второго.
172 TormozIT
 
гуру
29.03.13
17:24
(168) ничего не изменилось (замер для справочника без ТЧ)

Окончание замера "Подготовка объектного кэша" - Длительность = 7.082 с, Среднее = 0.007082 с
Окончание замера "Чтение с использованием объектного кэширования до 20сек" - Длительность = 0.016 с, Среднее = 0.000016 с
Окончание замера "Чтение с использованием объектного кэширования после 20сек" - Длительность = 6.739 с, Среднее = 0.006739 с
Окончание замера "Чтение отдельными запросами" - Длительность = 2.106 с, Среднее = 0.002106 с
Окончание замера "Чтение общим запросом" - Длительность = 0.094 с, Среднее = 0.000094 с
173 TormozIT
 
гуру
29.03.13
17:26
(168) + Если я правильно понял "закинь в тест запрос по 1 полю:ВерсияДанных", то менял ИмяПоля = "ВерсияДанных".
174 H A D G E H O G s
 
29.03.13
17:26
(171) Достаточно первого запроса, и, если он вернет версию, отличную от хранимой (что очень редко!) - то - 2 запрос.
175 H A D G E H O G s
 
29.03.13
17:27
(171) И тогда у теста в(172), для "Чтение с использованием объектного кэширования до 20сек" время будет не  6.739  секунд, а 2.1 секунды.
176 H A D G E H O G s
 
29.03.13
17:28
8.2.18:

Оптимизировано получение из базы данных прикладных объектов без табличных частей при вызове метода ПолучитьОбъект() и при обращении к свойствам «через точку» от ссылки.
177 TormozIT
 
гуру
29.03.13
17:28
(174) Да. Здравый смысл так говорит. Так что либо грязный эксперимент, либо ошибка платформы.
178 Aprobator
 
29.03.13
17:29
сам кэш в исполнении 1С хранится где вообще?
179 H A D G E H O G s
 
29.03.13
17:30
(178) Ты не поверишь :-)
180 TormozIT
 
гуру
29.03.13
17:30
(178) На сервере, но в каком именно процессе я точно не знаю.
181 TormozIT
 
гуру
29.03.13
17:30
(176) Ну если она исправление такого косяка назвали оптимизацией, то явно набивают цену)
182 Aprobator
 
29.03.13
17:32
(180) хотелось бы верить. Просто, исходя из (0), ощущение такое, что он хранится на клиенте.
183 H A D G E H O G s
 
29.03.13
17:32
Вот честно - я за хранение кэша подозреваю не
rphost а rmngr, судя по активности памяти и усиленной работе с файлом snccntx.000001CF.dat
184 Нога
 
29.03.13
17:35
(183) хорош флудить, иди в будвар уже
185 H A D G E H O G s
 
29.03.13
17:35
(180) Посмотри в первые 20 секунд тем же filemon-ом от Руссиновича, что за файлы читаются.
Я заметил только rmngr за чтением snccntx.000001CF.dat
186 Aprobator
 
29.03.13
17:39
+(182) вернее даже так, смысл этого запроса в том, чтобы сервер Предприятия 1С выполнял обращение непосредственно к серверу БД только 1 раз в любом случае.
187 Serginio1
 
29.03.13
17:40
(174) А зачем первый? Если второй запрос ничего не вернул, значит запись актуальна.
188 H A D G E H O G s
 
29.03.13
17:40
(184) Ждааать. Ждаааать. © Храброе Сердце.
189 Axel2009
 
29.03.13
17:41
(176) так ты прочитал что оптимизировано, или же протестил уже?
190 H A D G E H O G s
 
29.03.13
17:41
(187) Или хотя бы так, но так - хуже.
Надо же делать связку со всеми ТЧ. И в 99% случаев - вернется пустой результат.
191 Axel2009
 
29.03.13
17:41
(181) да походу они забыли про кэш давным давно и он не работал :)
192 H A D G E H O G s
 
29.03.13
17:42
(189) Счаст качается 18
193 Serginio1
 
29.03.13
17:42
(188) Ответь на 167. Интересно ведь.
194 H A D G E H O G s
 
29.03.13
17:43
(191) Посмотри типовую УПП, как там все через точку херачется. Я конечно думал, что там "хитрый смысл" и сделано специально, полез ковырять - и появилась эта тема.
195 TormozIT
 
гуру
29.03.13
17:47
По идее для таблиц без соединений (с ТЧ) оптимальным будет такой алгоритм, если прошло 20 сек
1. Строим запрос для чтения объекта (возвращает данные объекта, если версия изменилась), т.е. только второй запрос из (0)
4. Отправляем запрос в СУБД
5. Получаем результат из СУБД
6. Если результат не пустой, то помещаем его в кэш объектов.
7. Возвращаем объект из кэша.
196 Serginio1
 
29.03.13
17:48
(190) Все раввно если запрос вернул, значит запись изменилась и нужно тянуть табличные части. Убиваем 2 х зайцев. Второй запрос к ТЧ не будет тянуть Шапку.
197 TormozIT
 
гуру
29.03.13
17:49
А вот для таблиц с соединениями надо
1. Отправляем в СУБД запрос на получение версии
2. Получаем результат и проверяем актуальность кэша.
4. Если кэш не актуален, то отправляем запрос в СУБД на получение данных объекта
5. Получаем результат из СУБД и помещаем в кэш
7. Возвращаем объект из кэша.
198 Serginio1
 
29.03.13
17:50
(195) Кстати проверь для интереса скорость в транзакции. По уму через 20 секунд повторного чтения не должно быть
199 Serginio1
 
29.03.13
17:53
(197) Вообще можно сделать ХП в который передать текущую версию а он уже вернет набор всех таблиц если версия изменена.
200 H A D G E H O G s
 
29.03.13
17:53
18 проверить не получицца. Ключик тока один и там пока под 17 работает народ, так что тока на выходных.
201 TormozIT
 
гуру
29.03.13
17:54
(198) В транзакции ожидаемо быстро

Окончание замера "Подготовка объектного кэша" - Длительность = 1.56 с, Среднее = 0.00156 с
Окончание замера "Чтение с использованием объектного кэширования до 20сек" - Длительность = 0.016 с, Среднее = 0.000016 с
Окончание замера "Чтение с использованием объектного кэширования после 20сек" - Длительность = 1.95 с, Среднее = 0.00195 с
Окончание замера "Чтение отдельными запросами" - Длительность = 2.371 с, Среднее = 0.002371 с
Окончание замера "Чтение общим запросом" - Длительность = 0.094 с, Среднее = 0.000094 с
202 H A D G E H O G s
 
29.03.13
17:54
(201) Ух ты. А что так?
203 TormozIT
 
гуру
29.03.13
17:54
(201) Упс. Не быстро. Не увидел первую строку сразу)
204 H A D G E H O G s
 
29.03.13
17:55
(203) А что не так то?
205 H A D G E H O G s
 
29.03.13
17:56
Так, я нифига не понял произошедшее, надо оттестить с НачатьТранзакцию(), так? Я правильно понял?
206 TormozIT
 
гуру
29.03.13
17:57
(204) В (203) я писал про разницу между подготовкой кэша и чтением после 20сек.
А вот разница между даже подготовкой кэша и чтения отдельными запросами на лицо.
207 H A D G E H O G s
 
29.03.13
17:57
Почему НачатьТранзакцию() дает такой результат?
208 TormozIT
 
гуру
29.03.13
17:59
Транзакционный кэш заментно быстрее заполняется и обновляется, но разницы между безусловным чтением в него и обновлением после 20сек также не видно.
209 Serginio1
 
29.03.13
17:59
(201) Интересно а почему разница то до и после 20 сек.
Значит в 8 ке уровень рид комитед а не Repeatable read ?
210 Axel2009
 
29.03.13
18:00
(208) чей кэш? скульный или 1сный?
211 TormozIT
 
гуру
29.03.13
18:00
Для рассеивания сомнений привожу код теста еще раз

Сообщить(ТекущаяДата());
ВТранзакции = Истина;
Количество = 1000;
ИмяСправочникаБезГрупп = Метаданные.Справочники.ПодпискиКоманд2iS.Имя;
ИмяПоля = "ВерсияДанных";
//ИмяПоля = "ПометкаУдаления";
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ " + XMLСтрока(Количество) + "
|    Т.Ссылка
|ИЗ
|    Справочник." + ИмяСправочникаБезГрупп + " КАК Т";
МассивСсылок = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка"); //Готовим массив ссылок
Количество = МассивСсылок.Количество();
Сообщить("Размер выборки " + Количество);
Если ВТранзакции Тогда
   НачатьТранзакцию();
КонецЕсли;
УФ(сНачатьЗамер, Количество, "Подготовка объектного кэша");
Для Каждого Элемент ИЗ МассивСсылок Цикл
   Пустышка = Элемент[ИмяПоля];
КонецЦикла;
ДлительностьКэширования = УФ(сЗакончитьЗамер);
Если ДлительностьКэширования > 20 Тогда
   УФ(сСообщитьОбОшибке, "Длительность кэширования превысила 20 сек. Тест прекращен. Рекомендуется уменьшить количество элементов.");
   Перейти ~Конец;
КонецЕсли;

УФ(сНачатьЗамер, Количество, "Чтение с использованием объектного кэширования до 20сек");
Для Каждого Элемент ИЗ МассивСсылок Цикл
   Пустышка = Элемент[ИмяПоля];
КонецЦикла;
УФ(сЗакончитьЗамер);

УФ(сПодождатьЗаданноеВремя, 20);
УФ(сНачатьЗамер, Количество, "Чтение с использованием объектного кэширования после 20сек");
Для Каждого Элемент ИЗ МассивСсылок Цикл
   Пустышка = Элемент[ИмяПоля];
КонецЦикла;
УФ(сЗакончитьЗамер);

УФ(сНачатьЗамер, Количество, "Чтение отдельными запросами");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Т.Ссылка,
|    Т." + ИмяПоля + "
|ИЗ
|    Справочник." + ИмяСправочникаБезГрупп + " КАК Т
|ГДЕ
|    Т.Ссылка = &Ссылка";
Для Каждого Элемент ИЗ МассивСсылок Цикл
   Запрос.УстановитьПараметр("Ссылка", Элемент);
   Пустышка = Запрос.Выполнить().Выгрузить()[0][ИмяПоля];
КонецЦикла;
УФ(сЗакончитьЗамер);

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Т.Ссылка,
|    Т." + ИмяПоля + "
|ИЗ
|    Справочник." + ИмяСправочникаБезГрупп + " КАК Т
|ГДЕ
|    Т.Ссылка В(&МассивСсылок)";
Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
УФ(сНачатьЗамер, Количество, "Чтение общим запросом");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
   Пустышка = Выборка[ИмяПоля];
КонецЦикла;
УФ(сЗакончитьЗамер);
Если ВТранзакции Тогда
   ОтменитьТранзакцию();
КонецЕсли;
212 H A D G E H O G s
 
29.03.13
18:00
(210) Я думаю SQL_ный все же.
213 TormozIT
 
гуру
29.03.13
18:05
В документации про транзакционный кэш нашел пока это
"в рамках транзакции система использует отдельный кэш, поэтому обращение к данным объекта через ссылки в транзакциях гарантированно выдает актуальные данные"
214 Serginio1
 
29.03.13
18:05
(212) Ну кэш то на скуле имеется. При этом если транзакция Repeatable read то не смысла читать второй раз. По такому принципу должен быть и устроен транзакционный кэш 1с .
Из стать приведенной тобой
http://langslab.com/ebooks/prof-dev2/tome1/pr-dev-t1-ch04

Транзакционный кеш

Если обращение к данным происходит в рамках транзакции, то оно переадресуется транзакционному кешу. Транзакционный кеш по сути представляет собой ту же последовательную очередь, что и обычный кеш, за исключением того, что все данные, находящиеся в транзакционном кеше, являются валидными (гарантированно актуальными). При считывании данных в транзакционный кеш устанавливается блокировка на данные в базе данных, поэтому они гарантированно не могут быть изменены до окончания транзакции.
Транзакционный кеш хранит считанные данные до тех пор, пока они не будут вытеснены более поздними считанными данными или пока не закончится транзакция.
По окончании транзакции транзакционный кеш очищается, однако действия, выполняемые при этом, зависят от состояния завершения транзакции.
Если транзакция завершена успешно (Commit), данные всех объектов, содержащиеся в транзакционном кеше, переносятся в обычный кеш, а транзакционный кеш очищается (рис. 4.14).
215 H A D G E H O G s
 
29.03.13
18:09
(214) В статье ни одним духом не сказано, что это SQL-ный кэш, за что им хочется пожелать идти домой. Им - это авторам проф-разработки (статья оттуда).
216 TormozIT
 
гуру
29.03.13
18:10
Еще бы разобраться, где хранится внетранзакционный объектный кэш и где транзакционный. Пока 2 основных претендента rphost (у каждого свой кэш) и rmngr (общий для всех рабочих процессов). Логичнее всего конечно хранить в менеджере кластера rmngr и чтобы он был общий.
217 Serginio1
 
29.03.13
18:11
(215) Я говорил, что у скуля есть свой кэш. А ссылку привел на описание в статье, что скорость чтения в 1С в таком кэше не должна зависеть от времени.
218 Serginio1
 
29.03.13
18:15
(216) Ну все равно если они хранят и на сервере разницы по времени не должно быть. Если только они его не скидывают.
Тогда логичнее хранить по месту вызова.
219 TormozIT
 
гуру
15.04.13
14:33
Получил подтверждение от производителя, что
"в клиент-серверном режиме у клиента свой объектный кеш, а у сервера 1С свой".

Также он сообщил:
"Размер кеша определяется, как минимальное значение из объема доступной оперативной памяти компьютера и объема доступного виртуального адресного пространства процесса. При приближении объема занятого виртуального адресного пространства процесса 1С:Предприятия к этой величине кеш объектов начинает освобождаться форсированно. Возможности изменения правил вычисления максимального объема кеша объектов не предусмотрено."