#0
by H A D G E H O G s
День добрый. Понял, что заблуждался. создает объектный кэш. Кэш живет 20 МИНУТ (как оказалось), но через 20 секунд проверяется на валидность считывание поля _version из базы. Все нормально, все логично, пока. Заходим в профайлер и видим, что если мы выполним код ранее чем за 20 секунд - ничего не произойдет, а если после 20 секунд - выполниться 2! запроса: Первый запрос: exec sp_executesql N'SELECT T1._Version FROM _Reference152 T1 WHERE T1._IDRRef = ',N' varbinary',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 = AND T2._Version <> @P2',N' varbinary,@P2 varbinary',0x8041A8E513C95CF74D0C57393F6E2FDB,0x0000000000E96026 И вот тут то начинаются загадки...
#0
by H A D G E H O G s
День добрый. Понял, что заблуждался. создает объектный кэш. Кэш живет 20 МИНУТ (как оказалось), но через 20 секунд проверяется на валидность считывание поля _version из базы. Все нормально, все логично, пока. Заходим в профайлер и видим, что если мы выполним код ранее чем за 20 секунд - ничего не произойдет, а если после 20 секунд - выполниться 2! запроса: Первый запрос: exec sp_executesql N'SELECT T1._Version FROM _Reference152 T1 WHERE T1._IDRRef = ',N' varbinary',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 = AND T2._Version <> @P2',N' varbinary,@P2 varbinary',0x8041A8E513C95CF74D0C57393F6E2FDB,0x0000000000E96026 И вот тут то начинаются загадки...
#0
by H A D G E H O G s
День добрый. Понял, что заблуждался. создает объектный кэш. Кэш живет 20 МИНУТ (как оказалось), но через 20 секунд проверяется на валидность считывание поля _version из базы. Все нормально, все логично, пока. Заходим в профайлер и видим, что если мы выполним код ранее чем за 20 секунд - ничего не произойдет, а если после 20 секунд - выполниться 2! запроса: Первый запрос: exec sp_executesql N'SELECT T1._Version FROM _Reference152 T1 WHERE T1._IDRRef = ',N' varbinary',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 = AND T2._Version <> @P2',N' varbinary,@P2 varbinary',0x8041A8E513C95CF74D0C57393F6E2FDB,0x0000000000E96026 И вот тут то начинаются загадки...
#2
by H A D G E H O G s
Как я понимаю алгоритм: Тут либо 1 запрос и если версия изменилась - следом 2 запрос за новыми данными. либо 2 запрос, который вернет пустую таблицу (если данные непоменялись), либо новые данные. Но почему сразу 2 запроса?
#3
by H A D G E H O G s
T2._Version <> @P2 как бы говорит нам, что мы хотим версию, отличную от версии в кэшэ.
#5
by H A D G E H O G s
Все становиться веселее, если узнать, что 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 = AND T4._Version <> @P2 ORDER BY 9 ASC, T3._LineNo2362',N' varbinary,@P2 varbinary',0x8041A8E513C95CF74D0C57393F6E2FDB,0x0000000000E96026 Inner Join шапки с ТЧ. И все накрывается спелым мехом по производительности.
#7
by Serginio1
По уму если ты выполняешь код в транзакции Repeatable read или Snapshot повторное чтение не имеет смысла.
#9
by Serginio1
А Зачем на _Version индекс. Ключом является ._IDRRef, а поле _Version сообщает о текущей версии. Версия нужна для разрешения коллизий например при интерактивном редактировании записи.
#10
by H A D G E H O G s
Вот такой вот кусок кода дает следующие результаты на прогретом SQL-е тест1: Выполнено за 14 708 тест2: Выполнено за 3 398 тест3: Выполнено за 130
#20
by H A D G E H O G s
Единственная мысль - память не хватает на сервере 1С, вот он кэш и вырезает, сервер боевой
#22
by Конфигуратор1с
"Кэш живет 20 МИНУТ (как оказалось)," могу заблуждаться. но это еще в 8.0 писалось в книжках умных о том , что кэш живет двадцать минут
#25
by Конфигуратор1с
кстати. об этом тоже вродеписалось, что 20 минут он живет если память не переполняется.
#26
by Serginio1
Для интереса проверь два прохода в транзакции. Первый запрос не нужен, достаточно одного второго.
#28
by H A D G E H O G s
Мне все понятно насчет кэша, у меня простой вопрос - зачем 1С делает 2 запрос при наличии первого?
#29
by sapphire
Когда получаешь объектные данные, то 1С тянет весь объект целиком. Со всеми табличными частями и прочим. Т.е. при получении данных запросом оно потянет только то, что указано, т.е. ссылочные типы будут типизированы не более того, если начать перебор данных, то при обращении к ссылочному типу через точку будет вытянут весь объект целиком. Можно посмотреть трассировкой при выполнении кода.
#30
by Конфигуратор1с
Считанные данные будут находиться в кеше до тех пор, пока не наступит одно из четырех событий: ? считанные данные будут вытеснены из кеша другими считанными данными других объектов (переполнение кеша); ? при очередном обращении к кешу окажется, что считанные данные были изменены в базе данных; ? закончится интервал времени в 20 минут; ? данные будут изменены в базе данных. Все считанные данные помещаются в последовательную очередь, и, поскольку объем кеша ограничен, наиболее старые данные будут вытесняться из кеша последними считанными данными. При повторном обращении к кешу за данными уже считанного объекта будет анализироваться интервал времени, прошедший с момента появления данных в кеше. Если обращение происходит в пределах 20 секунд после поступления данных в кеш, данные считаются верными (валидными). Если интервал превысил 20 секунд, будет выполняться проверка на то, что версия данных, хранящихся в кеше, соответствует версии данных, находящихся в базе данных. Если окажется, что версии данных не совпадают (т. е. произошло изменение данных в базе данных), данные, находящиеся в кеше, будут удалены из него и выполнено повторное считывание данных из базы данных. Начиная с этого момента, начнется отсчет следующего 20-секундного интервала валидности этих данных.
#35
by Конфигуратор1с
я так понимаю ответ здесь Если обращение происходит в пределах 20 секунд после поступления данных в кеш, данные считаются верными (валидными). Если интервал превысил 20 секунд, будет выполняться проверка на то, что версия данных, хранящихся в кеше, соответствует версии данных, находящихся в базе данных. Если окажется, что версии данных не совпадают (т. е. произошло изменение данных в базе данных), данные, находящиеся в кеше, будут удалены из него и выполнено повторное считывание данных из базы данных. Начиная с этого момента, начнется отсчет следующего 20-секундного интервала валидности этих данных.
#38
by sapphire
Не совсем так, если первый не вернет ничего, то второго запроса не будет. Т.е. логика примерно такая - проверить надо ли что либо возвращать, еслит да то верни всё.
#41
by H A D G E H O G s
О том, что объект не изменился - должен говорить 1-ый запрос, либо 1-ого запроса вообще не должно быть. Где я не прав?
#45
by sapphire
Нет, они так сделали изначально, что версия ссылки на объект в памяти не хранится. Иначе зачем метод получения версии у объекта?
#46
by Serginio1
Если смотреть на устройства "объекта", то есть 2 вида устройства кэша .Объект имеет поля и свойства. Если поле не заполнено, то вызывается запрос. А вот сброс заполнения полей маловероятно. Второе есть кэш объектов в виде хэш таблицы и при доступе через свойство данные считываются из него. По уму кэши должны сбрасываться, по самому позднему скачиванию данных.
#49
by Лефмихалыч
а дак, а, если версия в памяти не хранится, как тогда понять, что объект не изменился?
#51
by Лефмихалыч
+ и метод там скорее всего, чтобы гарантировать неизменность поля _Version в объекте, а не чтобы запрос из метода выполнять
#55
by Serginio1
Первым запросом мы можем получить версию отличную от текущей и нет смысла её подставлять во второй запрос.
#57
by sapphire
>>чтобы гарантировать неизменность поля _Version в объекте, а не чтобы запрос из метода выполнять Неверно.
#59
by Serginio1
Кэш сам по сути вещь затратная, но упрощает создание кода. Хранить в кэше можно не все поля а только те которые вызываются, но судя по второму запросу считывается объект полностью.
#64
by H A D G E H O G s
Попробуйте открыть в 2-х сеансах 1 элемент справочника, во 2 сеансе измените и запишите его, а потом поменяйте наименование в 1 сеансе, увидьте "Данные были изменены или удалены" и запрос в SQL: exec sp_executesql N'SELECT T1._Version FROM _Reference13 T1 WITH(NOLOCK) WHERE T1._IDRRef = ',N' varbinary',0xA5FD001CC4BE9A3011E29148F9DACD38 и скажите, что версия не храниться в памяти.
#67
by sapphire
Не хранится версия в памяти. Просто при комите транзакции используется оповещение рефереров для конкретной ссылки.
#71
by H A D G E H O G s
Это _IDRRef , Анатолий... Вот, он вытаскивает _Version, сравнивает с тем, что у него в памяти сервера 1С на открытый объект и при разных значениях - выводит "данные изменены". Все просто.
#74
by Serginio1
Кластеров может быть не один. И оповещать различные кластера тоже не менее затратная.
#76
by H A D G E H O G s
Да я не против. Просто надо уменьшать уровень абстракции в общении, особенно не личном.
#77
by Serginio1
Ну в общем я уже давно высказался, что первый запрос не имеет смысла. Другое дело, что использовать кэш имеет смысл в транзакции. А 20 минут период большой и получить косяк из за кэша нет большого смысла.
#78
by sapphire
Имеет смысл, как раз для массивов и другой программной хрени, куда может входить объект.
#84
by Serginio1
По уму не имеет. Там где действительно нужен кэш, его легче организовать самому с минимальным набором необходимых полей и с запросом не по каждой ссылке а скопом. Так из-за одного артикула вторым запросом скачивается весь объект. А вот транзакционный кэш имеет бОльший смысл, т.к. хранится минимум времени только на этапе транзакции.
#85
by Sammo
Чтото мне имхается, что если первый скулевский запрос возвращает что-либо, то второго не будет (точнее не должно быть)
#92
by acsent
делать ленивую оптимизацию по каждому полю отдельно - невыгодно. хотя вот если бы тч атвоматом не читались было бы лучше
#93
by Эстет хренов
да я про тоже по сути, движения это другой объект согласен,имхо, чтение ТЧ объекта самое тяжелое, можно было поставить заглушку, и подгружать при первом обращении.
#95
by Odavid
>>О том, что объект не изменился - должен говорить 1-ый запрос, либо 1-ого запроса вообще не должно быть. Не совсем так, получается. Похоже, ответ такой: 1С ВСЕГДА берет полное соединение таблиц и вытягивает все данные (как и сказано в (_29)) - и после этого помещает их в кэш. Далее, идет работа с кэшем и, собственно, сам вопрос ТС. Первый запрос (в течении 20 секунд) - 1С считает данные однозначно валидными, и берет их из кэша - без проверки версии (получает только версию из базы - и уже по ней данные из кэша). "Если обращение происходит в пределах 20 секунд после поступления данных в кеш, данные считаются верными (валидными)." После 20 сек - данные в кэше уже НЕ СЧИТАЮТСЯ валидными, т.е, считаются ВОЗМОЖНО измененными в базе, поэтому они получаются заново ЦЕЛИКОМ для сравнения версии. Версия не изменилась - берет снова из кэша данные (и так в течении 20 минут). Версия изменилась - берет вновь полученные данные из базы, пишет в кэш, начинает отсчет следующих 20 минут. ("при очередном обращении к кешу окажется, что считанные данные были изменены в базе данных;"). Т.е.: - данные ВСЕГДА первоначально выбираются все связанные (из базы). - данные при любом раскладе проходят через кэш 1С. - кэш "отрабатывает" только в течении первых 20 секунд ("безусловно"), потом - дает прирост, только если получение данных 1С-сервером из "своего" кэша быстрее, чем заново считанных. Таким образом, 1С не ориентирована на кэширование "часто испоользуемых" данных и "интеллектуальную" выборку из кэша "только необходимого (отрабатывает полную выборку и только потом - сравнение версий)), + не рассчитана на обработку больших объемов данных (берет все данные из связанных таблицы из базы для обработки и отсеивания "ненужного" на 1С-сервере).
#96
by Odavid
первый запрос отрабатывает только для получения версии и БЕЗУСЛОВНОГО посика по ней данных в кэше. Т.е. 1С уверена на вссе 100, что данные не менялись в течении 20 секунд + они однозначно есть в кэше. А вот второй уже и делает ту самую проверку на валидность (сравнение версий), и далее отрабатывает два варианта из (_95).
#98
by H A D G E H O G s
После 20 сек - данные в кэше уже НЕ СЧИТАЮТСЯ валидными, т.е, считаются ВОЗМОЖНО измененными в базе, поэтому они получаются заново ЦЕЛИКОМ для сравнения версии. Смысл кэша после 20 секунд?
#99
by Odavid
>>Просто при комите транзакции используется оповещение рефереров для конкретной ссылки. согласен. Отсюда и кажущаяся "быстрота" обработки и "отсутствие" запроса по базе. "Запрос" в данном случае есть, только не по базе, а по "1С-серверу" (кэшу там своему или еще чего они туда вмудрили для этого), там же и ссылка на объект хранится.
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям
Похожие вопросы 1С
В этой группе 1С
- Отсутствуют потребности в номенклатуре. Нет необходимости использовать данный по
- Разные обороты по 21му счету между БУ и НУ
- 1С 8.2. УФ. НачалоВыбора и ДанныеВыбора
- Партии при УСН и РАУЗ
- v8: Не формируются проводки по учету ГП с использованием счета 40 в 1С УПП
- БухГосУчрежд.Перенос данных при смене типа учреждения
- ЗУП: Анализ неявок
- v7: Число фильтров субконто превысило допустимое значение
- УПП Разные данные отчета у разных пользователей
- БУХ. 3.0 не формируется книга доходов и расходов ИП на ОСНО
- В оборотном регистре есть ПРИХОД, РАСХОД, или надо сторно делать?
- Кодировка dbf-файла, создаваемого 1С...
- v7: Шрифт штрих-кода
- Как быть с запросом когда меняют порядок субконто в плане счетов?
- Сравнение строк зная имена колонок
- связь бух проводки с записью регистра накопления "Взаиморасчеты с контрагентами"
- Закрытие COM соединения
- Контроль остатков товаров при проведении УТ 11
- v7: Как получить остатки на каждый день прямым запросом
- ЗУП: Средне-списочная численность