|
Какой из запросов правильнее, а какой быстрее? | ☑ | ||
---|---|---|---|---|
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
|
||||
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
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |