|
Что быстрее? Запрос с группировкой по тч или функция Количество() тч? | ☑ | ||
---|---|---|---|---|
0
DirecTwiX
07.01.14
✎
18:50
|
Нужно выбрать документы, у которых в ТЧ 1 строка. Группировать или перебор выборки, использую Количество()?
Всё-таки группировка занимает n*ln(n) (минимум).. |
|||
1
МихаилМ
07.01.14
✎
18:54
|
если у тч есть поле номерстроки то поможно по нему отбирать.
|
|||
2
ptitsa-radio
07.01.14
✎
18:54
|
А перебор по-вашему, как работает? ))))
|
|||
3
ptitsa-radio
07.01.14
✎
18:56
|
ИМХО прямой запрос к таблице ТЧ, минуя шапку даст больше скорости, если считать количество, группируясь по полю Ссылка.
Перебор документов, с вызовом функции Количество() даст все равно неявное соединение двух таблиц, что будет медленнее, чем группировка в одной. |
|||
4
DirecTwiX
07.01.14
✎
18:58
|
(2) За один проход? "))))"
Есть массив ссылок, из них нужно отобрать те, у которых в ТЧ 1 элемент (1) Вариант. Спасибо. Но что по поводу (1)?) |
|||
5
ptitsa-radio
07.01.14
✎
19:04
|
Перебор работает путем перебора шапок документа. Они - в одной таблице. Чтобы посчитать количество строк в документе, нужно обратиться ко второй таблице, где хранятся строки.
Т. е. мы берем строку из первой таблицы - шапку, лезем во тороую и считаем там те строки, которые соотв. этой шапке. Получается соединение двух таблиц по ключевому полю. Если мы делаем запрос, то мы можем сразу обратиться ко второй таблице, где хранятся строки. В ней есть поле Ссылка (это ссылка на шапку дока в первой таблице) и по нему сгруппироваться. При этом к первой таблице мы не обращаемся вообще и соединения таблиц не делаем. Да, за один проход, причем, по одной только таблице мы можем получить количество строк в каждом документе. А в случае прямого перебора - придется проходить две таблицы, при этом их перемножая. |
|||
6
ptitsa-radio
07.01.14
✎
19:06
|
(1) Ну и НомерСтроки, ну и что? В любом документе будет строка с номером один, хрен ли по ней отбираться? Это ничего нам не скажет на тему того, есть ли в нем строка с номером два, и три и т. д.
Можно воспользоваться агрегатной функцией Макс (найти документы у которых максимальный номер строки = 1), но это, один хрен влечет за собой группировку по полю Ссылка в таблице строк документа. |
|||
7
DirecTwiX
07.01.14
✎
19:09
|
(5) Ничего не понял, но по-моему ты чего-то не понимаешь)
Группировка имеет сложность O(n*ln(n)) Проход по всем ссылка - O(n) Вопрос в том, сколько времени получится сэкономить запросом. (6)... Если там нет строки с номером 2, то там одна строка. |
|||
8
ptitsa-radio
07.01.14
✎
19:12
|
(7) Мне бы хотелось увидеть пример запроса, который бы устанавливал наличие отсутсвия строки с номером 2 )))
|
|||
9
ptitsa-radio
07.01.14
✎
19:15
|
Ребят, если вы не знаете, что такое декартово произведение двух таблиц, то вам очевидно рано задумываться о производительности.
Возьмите любой учебник про СУБД, почитайте азы теории. |
|||
10
DirecTwiX
07.01.14
✎
19:22
|
(8)
//////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ВедомостьНаВыплатуЗарплатыВБанкФизическиеЛица.Ссылка ПОМЕСТИТЬ СНесколькимиФизЛицами ИЗ Документ.ВедомостьНаВыплатуЗарплатыВБанк.ФизическиеЛица КАК ВедомостьНаВыплатуЗарплатыВБанкФизическиеЛица ГДЕ ВедомостьНаВыплатуЗарплатыВБанкФизическиеЛица.НомерСтроки = 2 И ВедомостьНаВыплатуЗарплатыВБанкФизическиеЛица.Ссылка В (ВЫБРАТЬ А.Ссылка ИЗ ВсеВедомостиСФизЛицом КАК А) ; //////////////////////////////////////////////////////////////////////////////// ВЫБРАТЬ ВсеВедомостиСФизЛицом.Ссылка ИЗ ВсеВедомостиСФизЛицом КАК ВсеВедомостиСФизЛицом ЛЕВОЕ СОЕДИНЕНИЕ СНесколькимиФизЛицами КАК СНесколькимиФизЛицами ПО ВсеВедомостиСФизЛицом.Ссылка = СНесколькимиФизЛицами.Ссылка ГДЕ СНесколькимиФизЛицами.Ссылка ЕСТЬ NULL полное соединение = декартово произведение. Оно будет всегда.. |
|||
11
ptitsa-radio
07.01.14
✎
19:28
|
(10) Декартова произведения не случится, если работать только с одной таблицей.
Запрос (шепотом) - трэш и угар )))) "Ссылка в ПОДЗАПРОС" - настойчиво рекомендую избегать данной конструкции. |
|||
12
DirecTwiX
07.01.14
✎
19:33
|
(11) Выдыхай и не позорься.
Подскажи пожалуйста, как избежать ССЫЛКА, если колонка так называется? Или, если я переименую, то тебе станет легче? Я с одной таблицей и работаю... |
|||
13
ptitsa-radio
07.01.14
✎
19:42
|
(12) Только хотела пример запроса написать. Но уже не буду. :-) А то позору не оберешься.
|
|||
14
DirecTwiX
07.01.14
✎
19:46
|
(13) Судя по твоим ответам, ты правильно сделал, что решил ничего не писать)
В (10) разве что можно было сделать выборку из временной таблицы, но это мелочи |
|||
15
zulu_mix
07.01.14
✎
20:30
|
выбрать док.ссылка как ссылка,
количество(док.реквизит) как строквтч поместить вт из документ.мойдокумент.имятч как док сгруппировать по ссылка ; выбрать ВТ.ссылка из ВТ как ВТ где ВТ.строквтч=1 |
|||
16
ptitsa-radio
07.01.14
✎
20:34
|
(15) тихо ржу
Разбаловали вас этими временными таблицами. В первом запросе используйте предложение ИМЕЮЩИЕ и будет нормальный фарш. По всем правилам стандарта. Без всяких виртуальных таблиц. |
|||
17
zulu_mix
07.01.14
✎
20:36
|
(16) мало ли что ему приспичит туда навалять. пусть вт использует
|
|||
18
ptitsa-radio
07.01.14
✎
20:41
|
(17) Не надо использовать ВТ. Надо использовать язык запросов. А ВТ нужно использовать по принципу бритвы Оккама - когда, действительно, без них уж никуда. Ибо любая ВТ, по сути дела - подзапрос. А подзапросов нужно избегать по мере возможности.
Автора я пыталась вразумить, но он что-то разволновался и быстро пришел в негодность. |
|||
19
zulu_mix
07.01.14
✎
20:42
|
(18) результаты замеров приведи
|
|||
20
Ork
07.01.14
✎
20:46
|
(18) Хотелось бы у вас сударыня уточнить по поводу декартова произведения.
Получится ли оно при Left Join, Right Join, Outer Join или InnerJoin соединении. Как повлияет на это произведение наличие индекса по полю связи? |
|||
21
zulu_mix
07.01.14
✎
20:50
|
(20) погодь, пусть она сначала замер сделает
|
|||
22
ptitsa-radio
07.01.14
✎
20:54
|
(21) Вы в своем уме? Шнурки токо поглажу и сразу побегу замерять. :-)
То, о чем я говорю - банальности, доступные любому студенту-первокурснику. Если кому-то недоступно, увы. Где-то человек чего-то недоучил. Нет, солнце нельзя сбить стрелой из лука. А от объяснений этого научного факта, я, пожалуй, воздержусь. Слишком разный уровень, чтобы было место для дискуссии. |
|||
23
zulu_mix
07.01.14
✎
20:58
|
(22) в чем заключается банальность? в твоем неумении пользоваться оптимальными алгоритмами? тут я согласен.
|
|||
24
Feunoir
07.01.14
✎
21:26
|
На дворе Рождество Христово, а вы такие вещи дьявольские говорите... Количество() по каждой ссылке из выборки - это надо же придумать такое. Для тех, кто в цикле запросы вызывает, в аду отдельная сковородка заготовлена.
|
|||
25
zulu_mix
07.01.14
✎
21:28
|
(24) ты вовремя. твой выход?
|
|||
26
Feunoir
07.01.14
✎
21:30
|
(25)
ВЫБРАТЬ РеализацияТоваровУслугТовары.Ссылка, КОЛИЧЕСТВО(*) КАК КоличествоСтрок ИЗ Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары СГРУППИРОВАТЬ ПО РеализацияТоваровУслугТовары.Ссылка ИМЕЮЩИЕ КОЛИЧЕСТВО(*) = 1 |
|||
27
Feunoir
07.01.14
✎
21:31
|
запрос выполняется 220 миллисекунд на выборке из 2500 документов, размер результата - 600 строк
|
|||
28
zulu_mix
07.01.14
✎
21:35
|
(27) а мой?
|
|||
29
zulu_mix
07.01.14
✎
21:40
|
только на скуле проверяй а не на файловой
|
|||
30
Feunoir
07.01.14
✎
21:48
|
(28) А вареньем не намазать? Я сейчас, в без пятнадцати двенадцать ночи буду проверять в разных позах, ага.
На файловой, на таких объемах - отличия в пределах погрешности. Медленнее на 4-8 миллисекунд. На SQL будет аналогично. Так как создание временной таблицы само по себе времени требует. И ещё в случае временной таблицы поиск ГДЕ вт.КоличествоСтрок = 1 точно пойдёт фулсканом. В случае единого запроса могут подхватиться индексы. ВТ оправданы в двух случаях: первое - если выборка сложная и медленная, а результат потом используется в нескольких местах. Второе - для упрощения понимания текста запроса. Оба критерия тут не подходят. |
|||
31
zulu_mix
07.01.14
✎
22:00
|
(30) а то что у тебя ИМЕЮЩИЕ выбирает так же как и ГДЕ - ниче?
и да, можно сделать индекс по кол-ву строк |
|||
32
zulu_mix
07.01.14
✎
22:07
|
а потом выяснится что надо еще данные других таблиц и понеслась...
|
|||
33
Шурик71
07.01.14
✎
22:22
|
с (26) может поспорить разве что вот это (индекс по ссылке/НомерСтроки может сыграть) ...
ВЫБРАТЬ док.Ссылка поместить вт ИЗ Документ.РеализацияТоваровУслуг.Товары КАК док Где док.НомерСтроки = 2 ; Выбрать док.Ссылка ИЗ Документ.РеализацияТоваровУслуг.Товары КАК док Левое соединение вт По док.ссылка = вт.ссылка Где док.НомерСтроки = 1 и вт.Ссылка есть null И то не факт... |
|||
34
ptitsa-radio
08.01.14
✎
04:55
|
(26) Я бы * заменила конкретным полем, желательно проиндексированным. Та же Ссылка, например.
КОЛИЧЕСТВО(Ссылка) КАК КоличествоСтрок будет работать быстрее, чем КОЛИЧЕСТВО(*) КАК КоличествоСтрок Особенно в таблицах, где много столбцов. Вообще, * в запросах лучше не использовать, а перечислять все нужные столбцы поименно. Реально повышает скорость. А в остальном - однозначно наиболее рентабельный вариант. Здесь даже и думать нечего, это первый класс, вторая четверть для любого СУБД-шника. "Школьники пишут запрос" - драма в трех действиях. :-) |
|||
35
mistеr
08.01.14
✎
05:26
|
(0)
ВЫБРАТЬ ПервыеСтроки.Ссылка ИЗ Справочник1.ТабличнаяЧасть1 КАК ПервыеСтроки ЛЕВОЕ СОЕДИНЕНИЕ Справочник1.ТабличнаяЧасть1 КАК ВторыеСтроки ПО ПервыеСтроки.Ссылка = ВторыеСтроки.Ссылка И ПервыеСтроки.НомерСтроки = 1 И ВторыеСтроки.НомерСтроки = 2 ГДЕ ВторыеСтроки.Ссылка ЕСТЬ NULL Без группировки. Без регистрации, без смс. |
|||
36
ptitsa-radio
08.01.14
✎
05:52
|
(35) Ну вот только таблицу саму на себя умножил, а так - красота.
Рассказать, как такой запрос будет работать в таблице на 100 000 строк, или сам догадаешься? Господа, а чем вам так всем группировки не угодили, боюсь спросить? С чего вы вдруг решили, что соединение двух таблиц может быть быстрее, чем группировка? Патамучта там индыксы? :-) |
|||
37
ptitsa-radio
08.01.14
✎
05:53
|
Открою страшную тайну - группировки тоже используют индексы. Причем, гораздо эффективней, чем соединения.
|
|||
38
catena
08.01.14
✎
06:52
|
Ну кстати, если в (35) взять РАЗЛИЧНЫЕ и убрать лишнее соединение ПервыеСтроки.НомерСтроки = 1, он по замерам лидирует. Проверяла на 34000 документах, результат выборки 15000.
|
|||
39
ptitsa-radio
08.01.14
✎
07:10
|
(38) Спорим, база файловая? ;-)
|
|||
40
catena
08.01.14
✎
07:13
|
(39)Не угадала.
|
|||
41
ptitsa-radio
08.01.14
✎
07:20
|
Какой документ тестили? Меня интересует среднее количество строк в каждом.
|
|||
42
ptitsa-radio
08.01.14
✎
07:21
|
Сосчитайте, пожалуйста, если не сложно.
|
|||
43
Нууф-Нууф
08.01.14
✎
07:22
|
Где есть номер строки 1 и нет 2. Тему развели...
|
|||
44
catena
08.01.14
✎
08:01
|
(41)ТребованиеНакладная. Количество документов 33995, в среднем 7,1 строк, максимально 140, с одной строкой 14921.
Текст1 = " ВЫБРАТЬ | РеализацияТоваровУслугТовары.Ссылка, | КОЛИЧЕСТВО(НомерСтроки) КАК КоличествоСтрок |ИЗ | Документ.ТребованиеНакладная.Материалы КАК РеализацияТоваровУслугТовары | |СГРУППИРОВАТЬ ПО | РеализацияТоваровУслугТовары.Ссылка | |ИМЕЮЩИЕ | КОЛИЧЕСТВО(НомерСтроки) = 1 "; Текст4 = " ВЫБРАТЬ различные | ПервыеСтроки.Ссылка |ИЗ | Документ.ТребованиеНакладная.Материалы КАК ПервыеСтроки | ЛЕВОЕ СОЕДИНЕНИЕ Документ.ТребованиеНакладная.Материалы КАК ВторыеСтроки | ПО ПервыеСтроки.Ссылка = ВторыеСтроки.Ссылка | И ВторыеСтроки.НомерСтроки = 2 | |ГДЕ ВторыеСтроки.Ссылка ЕСТЬ NULL "; В консоли Текст1 275мс, Текст4 175мс (в среднем на 10 запусках, подсчет только выполнения запроса без вывода) В замере производительности с перезагрузкой предприятия перед каждым запуском: http://i017.radikal.ru/1401/6a/06a45404d805.jpg |
|||
45
mistеr
08.01.14
✎
10:12
|
(38) РАЗЛИЧНЫЕ - это группировка. Ты как у меня потестируй.
(36) Где тут "умножение"? Левое соединение же. (37) >Причем, гораздо эффективней, чем соединения. Вот тут поподробнее, пожалуйста. Раскрой мысль. |
|||
46
catena
08.01.14
✎
10:29
|
(45)Это да, с РАЗЛИЧНЫЕ я погорячилась, прошу прощения :)
Но в неизменном виде запрос из (35) поставленной задачи не решает ;) |
|||
47
Classic
08.01.14
✎
11:02
|
ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка ИЗ Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг ГДЕ РеализацияТоваровУслуг.Товары.НомерСтроки = 1 И НЕ РеализацияТоваровУслуг.Товары.НомерСтроки = 2 |
|||
48
Classic
08.01.14
✎
11:03
|
Правда не уверен, что будет быстрее
|
|||
49
ptitsa-radio
08.01.14
✎
11:08
|
(47) вообще не взлетит )
|
|||
50
ptitsa-radio
08.01.14
✎
11:10
|
Условие представляет собой тавтологию. Запрос вернет все документы, в которых есть первая строка.
|
|||
51
catena
08.01.14
✎
11:12
|
(50)Да нет. Выборка же идет из документов, а не из ТЧ.
|
|||
52
Classic
08.01.14
✎
11:14
|
(50)
Взлетит |
|||
53
ptitsa-radio
08.01.14
✎
11:19
|
(51) Точно, не заметила.
Но это означает, что мы имеем неявное соединение двух таблиц: Шапки и ТЧ. Т. к. Выбираем мы по шапке, а условие проверяем в ТЧ. А может и не соедининеие, а вообще подзапрос. Я в душе не знаю, как 1с такую дикую конструкцию интрепретирует. Чес говоря,условие выглядит ужасно: А = 1 И НЕ А = 2 То, что 1с-ка это восприниамет, как должное, чести ей не делает ))) Слабо представляю, как это выглядит после интерпретации в классический SQL. |
|||
54
acsent
08.01.14
✎
11:19
|
(52) взлететь то взлетит, но результат совсем не тот будет
|
|||
55
ptitsa-radio
08.01.14
✎
11:21
|
(54) Как ни странно, но работает.
|
|||
56
acsent
08.01.14
✎
11:21
|
А если попробовать вместо
ИМЕЮЩИЕ КОЛИЧЕСТВО(*) = 1 ИМЕЮЩИЕ МАКСИМУМ(НомерСтроки) = 1 |
|||
57
ptitsa-radio
08.01.14
✎
11:25
|
Один фиг - ИМЕЮЩИЕ + агрегатная функция. Хотя, наверное, МАКСИМУМ в данном случае пошустрее будет, чем счетчик.
|
|||
58
acsent
08.01.14
✎
11:27
|
(57) но там же индекс есть кластерный по номеру строки
|
|||
59
ptitsa-radio
08.01.14
✎
11:28
|
(58) Да и по смыслу тоже понятно, что должно быстрей отрабатывать. Даже без индекса.
|
|||
60
acsent
08.01.14
✎
11:29
|
(59) без индекса не факт
|
|||
61
acsent
08.01.14
✎
11:29
|
без индекса даже наоборот
|
|||
62
ptitsa-radio
08.01.14
✎
11:31
|
Ну, в случае максимума, если мы видим строку с номером больше одного, сразу можно исключать из дальнейшей группировки этот док.
А в случаее счетчика мы обязаны сначала все досчтитать, а потом уже смотреть, где сколько строк получилось. Как-то так. |
|||
63
ptitsa-radio
08.01.14
✎
11:33
|
(62) Но это, разумеется очень сильно зависит от того, как СУБД строит план выполнения.
|
|||
64
ptitsa-radio
08.01.14
✎
11:34
|
Во всяком случае максимум медленее количества работать не должен. Хоть с индексом, хоть без индекса.
|
|||
65
Нууф-Нууф
08.01.14
✎
11:34
|
ВЫБРАТЬ
ЛимитноЗаборнаяКартаМатериалы.Ссылка, СУММА(ЛимитноЗаборнаяКартаМатериалы.НомерСтроки) КАК НомерСтроки ИЗ Документ.ЛимитноЗаборнаяКарта.Материалы КАК ЛимитноЗаборнаяКартаМатериалы СГРУППИРОВАТЬ ПО ЛимитноЗаборнаяКартаМатериалы.Ссылка ИМЕЮЩИЕ СУММА(ЛимитноЗаборнаяКартаМатериалы.НомерСтроки) = 1 |
|||
66
mistеr
08.01.14
✎
11:34
|
(46) Вот рабочий вариант
ВЫБРАТЬ ПервыеСтроки.Ссылка ИЗ Документ.ПоступлениеТоваровУслуг.Товары КАК ПервыеСтроки ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваровУслуг.Товары КАК ВторыеСтроки ПО ПервыеСтроки.Ссылка = ВторыеСтроки.Ссылка И (ВторыеСтроки.НомерСтроки = 2) ГДЕ ПервыеСтроки.НомерСтроки = 1 И ВторыеСтроки.Ссылка ЕСТЬ NULL По идее, должно идти только по индексам. |
|||
67
Нууф-Нууф
08.01.14
✎
11:35
|
не?
|
|||
68
acsent
08.01.14
✎
11:37
|
(64) Почему?
|
|||
69
mistеr
08.01.14
✎
11:38
|
(65) Можно еще добавить ГДЕ НомерСтроки <= 2, и получится оптимальный из всех вариантов с группировкой.
|
|||
70
acsent
08.01.14
✎
11:38
|
(62) А максимум не нужно разве вначале найти? А найти максимум - это сортировка
|
|||
71
Нууф-Нууф
08.01.14
✎
11:40
|
(69) зачем условие дополнительное накладывать. просто сложить и результат отфильтровать. зачем еще дополнительный отбор на начальном этапе
|
|||
72
mistеr
08.01.14
✎
11:47
|
(71) Уменьшить объем данных для группировки. Вдруг там большие ТЧ.
|
|||
73
Нууф-Нууф
08.01.14
✎
11:49
|
(72) так вроде суммирование не сильно сложная функция.
|
|||
74
mistеr
08.01.14
✎
11:58
|
(73) Так я не про сложность, а про объем. Объем == I/O.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |