Имя: Пароль:
1C
1С v8
Какой из запросов правильнее, а какой быстрее?
,
0 WED
 
26.09.12
23:17
Имеем:
Документ "Док".
В "Док" есть ТЧ "Изделия".
В "Изделия" есть реквизит "Изделие" - ссылка на спр.Изделия.
У документа индексация по "Изделие" включена.

Изделие может быть только в одном из "Док".

Какой запрос более правильный с точки зрения методологии, а какой быстрее работает:

1.

ВЫБРАТЬ
   ДокИзделия.Ссылка
ИЗ
   Документ.Док.Изделия КАК ДокИзделия
ГДЕ
   ДокИзделия.Изделие = &Изделие

2. ВЫБРАТЬ
   Док.Ссылка
ИЗ
   Документ.Док КАК Док
ГДЕ
   Док.Изделия.Изделие = &Изделие
1 DrShad
 
26.09.12
23:20
2
2 PR
 
26.09.12
23:20
Первый думаю конечно же
3 PR
 
26.09.12
23:20
(1) Почему? Там же будет соединение с ТЧ вроде?
4 Шифровальщик2012
 
26.09.12
23:20
(2) а вариант 2 разве рабочий?
5 WED
 
26.09.12
23:21
(2) Да
6 Шифровальщик2012
 
26.09.12
23:22
Имхо так правильнее:
ВЫБРАТЬ РАзличные
   ДокИзделия.Ссылка
ИЗ
   Документ.Док.Изделия КАК ДокИзделия
ГДЕ
   ДокИзделия.Изделие = &Изделие
7 WED
 
26.09.12
23:22
(4) Рабочий. Но мне кажется более медленный. Чисто интуитивно. Поэтому вопрос и возник.
8 WED
 
26.09.12
23:23
(6) Зачем? Изначально известно, что Изделие только в одном из Док.
9 Шифровальщик2012
 
26.09.12
23:24
(6) так не бывает :)
10 Шифровальщик2012
 
26.09.12
23:26
Имхо, вариант 2 плох. Там соединяться будут две таблицы. Даже не знал, что такой вариант может быть.
11 H A D G E H O G s
 
26.09.12
23:27
(8) Документ известен?
12 WED
 
26.09.12
23:27
(10) В первом варианте разве не будут две таблицы соединяться? По-моему тоже будут.
13 WED
 
26.09.12
23:27
(11) нет. его и надо найти
14 Шифровальщик2012
 
26.09.12
23:28
+(10) индексация, возможно ускорит соединение, но смысл индексировать чтобы соединить, если можно напрямую из одной таблицы выбрать?
15 MrStomak
 
26.09.12
23:28
Тут даже обсуждать нечего, однозначно 1й вариант. Во втором мы имеем разыменование, неявное соединение с еще одной таблицей, Невозможность перебора таблицы по индексу - явный фэил в общем. Это кстати элементарно проверить трассировкой MS SQL
16 H A D G E H O G s
 
26.09.12
23:29
(13) Тогда и вопроса не стоило задавать,
17 WED
 
26.09.12
23:30
(16) Это почему же? Вопрос в том и был - каким запросом быстрее Док найти зная Изделие.
18 WED
 
26.09.12
23:31
(15) База файловая. Скуля нет.
19 MrStomak
 
26.09.12
23:31
Плюс даже в управляемом режиме блокировок возможно ловить проблемы из-за обеспечения Read Committed, любой писатель в таблицу документов наставит блокировку и полный скан таблицы отложится.
20 PR
 
26.09.12
23:31
(12) С фига ли?
21 H A D G E H O G s
 
26.09.12
23:31
(17) Судя по твоим вопросам - ты в восьмерке 5.5 лет.
Вопроса не стоило задавать.
22 MrStomak
 
26.09.12
23:33
(12) в первом запросе напрямую обращение к таблице ТЧ будет, никаких соединений
23 WED
 
26.09.12
23:34
(22) т.е. 1С возьмет таблицу ТЧ, наложит фильтр по "изделие" и с результата получит ссылку. Так?

а во-втором запросе как будет?
24 Шифровальщик2012
 
26.09.12
23:34
(19) если режим конфигурации управляемый и бд не файловая, то запрос спокойно отработает по таблице документов грязным чтением.
25 MrStomak
 
26.09.12
23:35
(24) грязное чтение надо жестко включать на СУБД, по умолчанию будет read committed. Если СУБД версионник, то будет получена версия на начало транзакции, но это не есть грязное чтение.
26 WED
 
26.09.12
23:36
(21) Да вот что-то ступор какой-то с этими двумя вариантами. :) Вроде и понимаю, что первый запрос по всем показателям лучше, но второй тоже возможен, а как он отрабатывается не могу понять.
27 Шифровальщик2012
 
26.09.12
23:37
(25) А разве грязное чтение - это не чтение из БД по состоянию БД на момент чтения записи?
28 MrStomak
 
26.09.12
23:37
(23) СУБД будет обращаться к таблице ТЧ документов. Она посомтрит индекс и оценит, сколько строк результат стоит ждать. Раз ты говоришь там 1 док только, то будет составлен план запроса переборки ТЧ через индекс.
29 MrStomak
 
26.09.12
23:38
(27) Грязное чтение - это когда внутри одной транзакции два селекта с одинаковыми отборами выдадут разный результат.
30 MrStomak
 
26.09.12
23:40
(23) второй запрос будет через соединение двух таблиц по ссылке. Ссылка тоже проиндексирована, но запрос к двух таблицам даёт меньше шансов составить максимально эффективный способ перебора оптимизатору.
31 ChAlex
 
26.09.12
23:41
А чего гадать? А протестить призводительность - проблема?
32 WED
 
26.09.12
23:43
(31) Проблема - База пустая :)
(30) Ну и всё тогда. Вывод прост: первый запрос быстрее и правильнее. потому что используется только 1 таблица базы данных.
33 H A D G E H O G s
 
26.09.12
23:44
(28) Вот не факт
34 H A D G E H O G s
 
26.09.12
23:44
(28) Далекоооо не факт
35 WED
 
26.09.12
23:45
(33,34) Объясни :)
36 WED
 
26.09.12
23:46
(31) Дело не в гадании, а в понимании работы 1С с такими запросами.
37 H A D G E H O G s
 
26.09.12
23:46
(28)
Помогите понять индексы MS SQL

пост 13, 18 и вывод в постам 36, 53
38 MrStomak
 
26.09.12
23:46
(34) Что не факт? Скан индекса? Конечно не факт, от статистики будет зависеть. То, что будет скан 1й таблицы - факт.
39 Шифровальщик2012
 
26.09.12
23:47
(25) т.е. ты хочешь сказать, что если я заблокирую документ, то запрос, работающий по таблице документов остановится и будет ждать пока документ разблокируется?

Я думаю, он прочитает то, что есть в таблице.
40 H A D G E H O G s
 
26.09.12
23:49
Хотя нет, я перепутал
41 H A D G E H O G s
 
26.09.12
23:50
При годной статистике, при высокой селективности (как у меня в примере (37)) - будет TableScan, при низкой - IndexScan
42 H A D G E H O G s
 
26.09.12
23:50
У автора будет IndexScan, так как записей мало (1-а, изделие одно же)ю
43 MrStomak
 
26.09.12
23:52
(39) Если будет произведена запись в таблицу документа и селект предусматривает полный скан таблицы, то да, если это блокировочник.
44 MrStomak
 
26.09.12
23:53
(42) Ну в общем я про это и говорил вроде
45 WED
 
26.09.12
23:56
(44) Не, я конечно рад, что вы договорились. Мне по-русски объясните? Ну или скажите где почитать. Как-то далек я оказался от прямой работы с таблицами в SQL, слишком смутно понимаю о чем вы договорились :)
46 Шифровальщик2012
 
26.09.12
23:56
(43) А я почему-то думаю, что на SQL и управляемых блокировках 1с в запрос попадут существующие в таблице записи и записанные на момент чтения.
47 H A D G E H O G s
 
26.09.12
23:57
(45) Мне кажется, ты - троллишь?
48 Шифровальщик2012
 
26.09.12
23:57
+(46) и нифига запрос не застопорится, просто выдаст белиберду из существующих записей и тех, которые успели записаться, пока он шерстил таблицу и не дошел до них
49 WED
 
27.09.12
00:01
(47) Не. Вопрос на самом деле был. Выводы я сделал - первый запрос правильнее по причине работы 1С (как СУБД, ибо база файловая) с 1 таблицей данных. Но, смотрю, вы тут уже глубоко стали копать. Я с этой стороной не сталкивался настолько глубоко, вот и стало интересно. Смутно понимаю о чем речь - насколько общих знаний по СУБД, но такие детали...
50 H A D G E H O G s
 
27.09.12
00:03
(49) Воооот это почитай.

Именно эту статью я бы преподавал в универе студням до потери пульса.
http://www.sql.ru/articles/mssql/03013101indexes.shtml
51 MrStomak
 
27.09.12
00:04
(48) Друг, мне неинтересно что ты там думаешь. Версионник отдаст данные на начало транзакции, MS SQL наложит блокировку на запись до конца транзакции записи - это суровая правда жизни.
52 Шифровальщик2012
 
27.09.12
00:06
(51) а разве блокировка на запись - это не просто флажок в строчке таблицы?
53 WED
 
27.09.12
00:07
(50) За ссылку спасибо. :)
54 Шифровальщик2012
 
27.09.12
00:08
+(52)  тебе не кажется, что само понятие "блокировка на запись" говорит о том, что это блокировка для других транзакий, пытающихся записать?
А запрос читать может что угодно?
55 acsent
 
27.09.12
00:10
(54) есть несколько режимов чтения
56 acsent
 
27.09.12
00:11
и вообще разве транзакция сама по себе что-то блокирует?
57 Шифровальщик2012
 
27.09.12
00:13
+(54)  может, конечно, я туп как пробка, но даже фирма одынес рекомендует накладывать блокировки только в том случае, если читаемые записи должны остаться неизменными пока не завершится транзакция...

Т.е. запрос тупо читает то, что есть в таблице. А неизменность того, что есть в таблице, обеспечивают наложенные ранее управляемые блокировки.
58 Шифровальщик2012
 
27.09.12
00:15
(55) дык вот на курсах, лично Габец мне говорил, что в режиме управляемых блокировок одинес читает в запросах то, что есть в таблице. Ей плевать на то, что в строке таблицы SQL установлен флажок "заблокировано".
59 MrStomak
 
27.09.12
00:20
(58) Ты жестоко ошибаешься. СУБД и без 1С обеспечивает заданный уровень изоляции транзакций. Просто когда 1с в автоматическом режиме, этот уровень более высокий. Выполнить грязное чтение в управляемом режиме блокировок не получится. Read Committed пишется в мануале к 1с как уровень изоляции, использующийся для всех СУБД, кроме файловой, в управляемом режиме. Это не выдумки - это как бы факты.
60 MrStomak
 
27.09.12
00:22
(58) ну и блокировка - она как бы в менеджере блокировок хранится, а не в СУБД, не понимаю про что ты говоришь.
61 Шифровальщик2012
 
27.09.12
00:24
(59) а еще на курсах мне объясняли, что если конфигурация работает в полностью управляемом режиме, то без применения управляемых блокировок, запрос читает то, что ему выдает СУБД.
Т.е. уровень изоляции транзакий опускается до уровня СУБД.

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

З.Ы. Это если не писать блокировки.
62 MrStomak
 
27.09.12
00:28
(61) Друг.
Хватит.
Уровень изоляции транзакций опускается до базового уровня для СУБД. Этот уровень - read committed. Далее заисит от того, как СУБД его обеспечивает. MS SQL накладывает исключительные блокировки на подвергшиеся update записи. Я не понимаю, что за желание козырять какими-то курсами, когда можно трассировкой всё увидеть вживую.
63 Шифровальщик2012
 
27.09.12
00:32
(62) Товарищь, мне плевать что там в SQL происходит (я об этом даже не задумываюсь), я тебе пишу о том, что если клиентская оболочка в виде одинеса работает  у режиме управляемых блокировок, то запросы, которые валятся из неё в сервер предприятия, читают то, что выдает SQL без всяких ограничений.

И если ты будешь строить отчет, а в это время по данным отчета пройдут изменения, то ты получишь мешанину.
64 shuhard
 
27.09.12
00:35
(17)[Это почему же? Вопрос в том и был - каким запросом быстрее Док найти зная Изделие.]
ты будешь удивлён, но в типовой это сделано критерием =)
65 WED
 
27.09.12
00:37
(64) Удивлен. Можно подробней :)
66 shuhard
 
27.09.12
00:38
(65) открой УПП и увидишь как по спецификации находится изделие и наоборот =)
67 H A D G E H O G s
 
27.09.12
00:39
(63) Открой иногда профайлер, ага
68 H A D G E H O G s
 
27.09.12
00:40
(63) Когда ты пишешь
БлокировкаДанных.Заблокировать();

1С переводит SQL из READ COMMITTED в REPEATABLE READ на период транзакии.
69 WED
 
27.09.12
00:42
(66) Под рукой нет, а качать сейчас не охота. Может логику так - на пальцах можешь рассказать?
70 MrStomak
 
27.09.12
00:42
(63) Ты хочешь отстраниться от того, что творится в SQL, а это невозможно.  SQL будет выдавать не всё подряд, а в соответствии со своим уровнем изоляции транзакций. И мешанина в отчете, естественно, возможна - insert, например, сработает без каких-либо проблем и блокировок.
71 shuhard
 
27.09.12
00:48
(69) логика проста, посредством критерия ты строишь связь реквизита табличной части и документа

и эту связь 1С хранит в отдельной таблице

и эта таблица доступна языку запросов
72 WED
 
27.09.12
00:54
(71) Как работают критерии я знаю. Я не пользовался критериями в запросах, хотя мне кажется это не быстрее моего первого запроса из (0).
По сути кроме добавления в "перейти" критерии мне ничего не дадут.
73 ssh2006
 
27.09.12
01:15
(68)  БлокировкаДанных.Заблокировать() - вроде как это установка только для собственного менеджера блокировок и на sql не влияет, там  READ COMMITTED