|
Как оптимизировать запрос... | ☑ | ||
---|---|---|---|---|
0
Ministr
18.06.14
✎
12:42
|
Привет, всем! В УПП - есть регистр сведений "Версии объектов", измерение "Объект" - составной тип содержит все справочники и все документы. Необходимо выбрать версии по определенным типам объекта. Я написал следующий запрос..:
ВЫБРАТЬ ВерсииОбъектов.Объект, ВерсииОбъектов.НомерВерсии, ВерсииОбъектов.ВерсияОбъекта, ВерсииОбъектов.АвторВерсии, ВерсииОбъектов.ДатаВерсии ИЗ РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов ГДЕ (ВерсииОбъектов.Объект ССЫЛКА Документ.ВводНачальныхОстатковОС ИЛИ ВерсииОбъектов.Объект ССЫЛКА Документ.ИзменениеСпособовОтраженияРасходовПоАмортизацииОС ИЛИ ВерсииОбъектов.Объект ССЫЛКА Документ.КорректировкаЗаписейРегистров ИЛИ ВерсииОбъектов.Объект ССЫЛКА Документ.ПринятиеКУчетуОС) Как сделать более оптимально? Недавно прочитал статью про составной тип данных - понял, что при неумелом пользовании в запросах.. можно дорого заплатить по времени) |
43 54 125 130 |
||
35
Fragster
гуру
18.06.14
✎
13:17
|
(33) откуда там будет соединение-то?
|
39 |
||
36
Широкий
18.06.14
✎
13:18
|
(32) Ты план запроса смотри
|
|||
37
Широкий
18.06.14
✎
13:19
|
+36 а лучше покажи
|
|||
38
Maxus43
18.06.14
✎
13:19
|
(33) не будет никаких соединений без залезания "внутрь" составного типа за реквизитом
|
|||
39
Крошка Ру
18.06.14
✎
13:20
|
(35) Хотя вообще, да, из регистра же данные тащим
|
|||
41
H A D G E H O G s
18.06.14
✎
13:24
|
StmtText
Clustered Index Seek(OBJECT:([database].[dbo].[_InfoRg24333].[_InfoR24333_ByDims_RN] AS [T1]), SEEK:([T1].[_Fld24334_TYPE]=0x08 AND [T1].[_Fld24334_RTRef]=0x00000104 OR [T1].[_Fld24334_TYPE]=0x08 AND [T1].[_Fld24334_RTRef]=0x00000147 OR [T1].[_Fld24334_TYPE]=0x08 AND [T1].[_Fld24334_RTRef]=0x0000015F OR [T1].[_Fld24334_TYPE]=0x08 AND [T1].[_Fld24334_RTRef]=0x000001C8) ORDERED FORWARD) |
43 44 |
||
42
Жан Пердежон
18.06.14
✎
13:26
|
а где вариант с ОБЪЕДИНИТЬ ВСЕ?
|
|||
43
Широкий
18.06.14
✎
13:26
|
||||
44
MrStomak
18.06.14
✎
13:34
|
(41) Ты понимаешь, что индекс здесь используется по признаку Ссылка, а не по признаку Документ.чтото ?
|
45 46 |
||
45
H A D G E H O G s
18.06.14
✎
13:37
|
(44) Чего?
|
47 |
||
46
H A D G E H O G s
18.06.14
✎
13:38
|
(44) Я не понял твоего каммента.
|
48 |
||
47
Fragster
гуру
18.06.14
✎
13:38
|
48 |
|||
48
MrStomak
18.06.14
✎
13:47
|
(47) В курсе
(46) Из твоего поста я понял (32), что используется предикат по полю T1._Fld24334_TYPE в физическом операторе. Это был бы частичный поиск по индексу, так как нужно использование двух полей. Проверил сам - в предикатах поиска присутствует также второе поле. |
49 |
||
49
H A D G E H O G s
18.06.14
✎
13:52
|
(48)
Ты очень сложно выражаешь свои мысли. Давай я проще: 1С наложила условие на Класс метаданных (справочник/документ/ПВХ/БизнесПроцесс) и на тип класса метаданных (Документ.ВводОстатков/Документ.РТУ). И это прекрасно. Не наложи она условия на Класс метаданных (_Fld24334_TYPE]=0x08) индекс бы пошел лесом. |
54 |
||
50
H A D G E H O G s
18.06.14
✎
13:58
|
Понапридумывали тут.. (ворчит)
http://www.sql.ru/articles/mssql/2007/012302seekpredicates.shtml Для следующих ниже примеров, мы можем использовать индекс для удовлетворения условий предиката для столбца "a", но не для столбца "b". В этих случаях потребуется остаточный предикат: a > 100 and b > 100 a like 'abc%' and b = 2 |
57 |
||
51
H A D G E H O G s
18.06.14
✎
13:59
|
"потребуется остаточный предикат"
Объясните мне, как это по русски. indexseek+indexscan? как это выглядит в профайлере? |
53 |
||
52
H A D G E H O G s
18.06.14
✎
14:00
|
Вот так правильно условия:
a > 100 and b > 100 a like 'abc%' and b = 2 |
56 |
||
53
MrStomak
18.06.14
✎
14:00
|
(51) В профайлере это выглядит как разделение в тексте плана запроса SEEK и WHERE, но всё это будет index seek
|
55 |
||
54
MrStomak
18.06.14
✎
14:02
|
(49) Если преобразовать текст запроса из (0) так:
ВЫБРАТЬ ВерсииОбъектов.Объект, ВерсииОбъектов.НомерВерсии, ВерсииОбъектов.ВерсияОбъекта, ВерсииОбъектов.АвторВерсии, ВерсииОбъектов.ДатаВерсии ИЗ РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов ГДЕ (ВерсииОбъектов.Объект ССЫЛКА Документ.ВводНачальныхОстатковОС ИЛИ ВерсииОбъектов.Объект ССЫЛКА Документ.ИзменениеСпособовОтраженияРасходовПоАмортизацииОС ИЛИ ВерсииОбъектов.Объект ССЫЛКА Документ.КорректировкаЗаписейРегистров ИЛИ ВерсииОбъектов.Объект ССЫЛКА Документ.ПринятиеКУчетуОС или версииобъектов.объект = значение(Документ.ПринятиеКУчетуОС.ПустаяСсылка)) ,то тоже будет Index seek, тоже будут в условии запроса все поля, но при этом будет использоваться только индекс по первому полю TYPE. Я из твоего поста подумал, что именно это и произошло. |
|||
55
H A D G E H O G s
18.06.14
✎
14:03
|
(53) Счаст пытаюсь представить себе физический смысл "a > 100 and b > 100" для b дерева и не понимаю проблемы.
|
56 58 |
||
56
MrStomak
18.06.14
✎
14:05
|
57 |
|||
57
H A D G E H O G s
18.06.14
✎
14:06
|
||||
58
MrStomak
18.06.14
✎
14:11
|
(55) Как ты это сделаешь, кроме как сначала выбрав все записи где а>100, а потом, уже из них, где b>100?
|
59 60 |
||
59
H A D G E H O G s
18.06.14
✎
14:16
|
(58) Индексное дерево для 2-х полей строится одно?
|
|||
60
H A D G E H O G s
18.06.14
✎
14:16
|
(58) Или для каждого поля - отдельное дерево. Для полей, в составном индексе.
|
61 |
||
61
MrStomak
18.06.14
✎
14:19
|
(60) Как может быть несколько деревьев в индексе? Одно дерево.
|
|||
62
H A D G E H O G s
18.06.14
✎
14:21
|
Ядро СУБД Cach? использует B+-деревья для хранения данных...
После имени глобала в круглых скобках через запятую указывается произвольное количество индексов. Компилятор осуществляет преобразование всего множества индексов в ключ B+-дерева... Вот. Тоесть, при выполнении условия "a > 100 and b > 100", это условие должно преобразоваться в условие вида "key>100" |
|||
63
H A D G E H O G s
18.06.14
✎
14:22
|
И потом выполнить типовой поиск по B+ дереву.
|
|||
64
H A D G E H O G s
18.06.14
✎
14:23
|
Хотя нет.
|
|||
65
H A D G E H O G s
18.06.14
✎
14:24
|
Ключом B+ дерева тут будет скорее всего Структура с элементами
[a,b] Или хэш. Блин. |
|||
66
H A D G E H O G s
18.06.14
✎
14:27
|
Нет. Нельзя хэш. Нам нужны исходные данные.
|
|||
67
H A D G E H O G s
18.06.14
✎
14:27
|
Например, для получения данных через индекс.
|
|||
68
MrStomak
18.06.14
✎
14:32
|
Хэш используется для соединений, в индексе мы последовательно сверяем куски известного ключа со значениями для каждой "развилки".
|
69 70 |
||
69
H A D G E H O G s
18.06.14
✎
14:33
|
(68) Ты, скорее всего, меня не понял.
|
|||
70
H A D G E H O G s
18.06.14
✎
14:36
|
(68)
wiki:B-%E4%E5%F0%E5%E2%EE#mediaviewer/Файл:B-tree-definition.png Что находиться в КЛЮЧЕ корневого узла k1, индексного дерева для полей а, b таблицы, в которой поле a имеет значения от 0 до 100, поле b имеет значение от 100 до 200. Я вот думаю - там структура со значениями 50,100 |
72 73 124 |
||
71
H A D G E H O G s
18.06.14
✎
14:38
|
||||
72
MrStomak
18.06.14
✎
14:49
|
(70) Почему 50,100? Там должна быть конкатенация значений всех ключей.
|
74 75 |
||
73
MrStomak
18.06.14
✎
14:49
|
(70) Точнее, всех полей.
|
|||
74
H A D G E H O G s
18.06.14
✎
14:51
|
(72) как потом вытаскивать данные, ну, допустим при indexscan?
|
76 |
||
75
H A D G E H O G s
18.06.14
✎
14:52
|
(72) Как сконкатенировать date и nvarchar?
|
|||
76
MrStomak
18.06.14
✎
14:52
|
(74) первые столько-то байт - первое поле, вторые столько-то байт - второе поле
|
77 |
||
77
H A D G E H O G s
18.06.14
✎
14:53
|
(76) Тупо побайтовый набор? Это и есть Структура.
|
78 |
||
78
MrStomak
18.06.14
✎
14:55
|
(77) я думал, у тебя 50,100 означало разные узлы, где значение только а, а не структуру со значениями а и б.
|
|||
79
MrStomak
18.06.14
✎
14:55
|
Ну да, так будет узел выглядеть, 50,100
|
80 |
||
80
H A D G E H O G s
18.06.14
✎
14:56
|
(79) Отлично!
|
|||
81
MrStomak
18.06.14
✎
15:03
|
добравшись до узла , где a=100, мы знаем, что всё остальное точно удовлетворяет предикату a>100 и отбираем это. Если мы продолжаем поиск, и находим удовлетворение условию b>100, то это совсем не означает, что все остальные строки удовлетворяют этому условию! Потому что там дальше может быть а=110, б=2, следующая запись а=110 б = 112, потом опять а=111 б = 1. Дальше как ни крути, нужно выполнять скан всех строк индекса.
|
82 |
||
82
H A D G E H O G s
18.06.14
✎
15:04
|
(81) Стоп. А разве дерево не отсортировано?
|
84 |
||
83
wade25
18.06.14
✎
15:05
|
Соединяй правым соединение с таблицами этих документов, будет отбор на уровне SQL, отработает быстро.
|
89 |
||
84
MrStomak
18.06.14
✎
15:05
|
(82) Отсортировано. Вот тебе порядок - 110 2, 110 112, 111, 1.
Это всё в порядке сортировки побайтовой конкатенации значений полей. |
86 87 |
||
85
MrStomak
18.06.14
✎
15:06
|
В B-дереве чтобы выполнять поиск по всем полям у нас необходимое условие, чтобы предикаты на все поля, кроме последнего, были на эквивалентность.
|
|||
86
H A D G E H O G s
18.06.14
✎
15:07
|
(84) таймаут! Пошел думать.
|
|||
87
H A D G E H O G s
18.06.14
✎
15:08
|
(84) Почему то мне кажется, что сортировка будет не по конкатенации байтов, а по значения полей.
|
|||
88
H A D G E H O G s
18.06.14
✎
15:08
|
а по значения полей.-> а по значениям полей.
|
91 |
||
89
MrStomak
18.06.14
✎
15:08
|
(83) *грустно смотрит*
|
93 |
||
90
H A D G E H O G s
18.06.14
✎
15:08
|
В корне у нас должны быть серединки диапазонов.
|
94 |
||
91
MrStomak
18.06.14
✎
15:08
|
(88) какая разница?
|
|||
92
H A D G E H O G s
18.06.14
✎
15:09
|
Все. Это для меня слишком сложно. Мне нужно на бумажке начертить дерево и карандашиком поискать по нему.
|
97 |
||
93
wade25
18.06.14
✎
15:10
|
(89) Пробовал, что бы критиковать? Мб не так причину скорости выполнения написал, но это работает ;)
|
95 |
||
94
MrStomak
18.06.14
✎
15:10
|
(90) Ключ один, какие серединки?
|
96 |
||
95
MrStomak
18.06.14
✎
15:10
|
(93) тут уже профайлером выяснили, что идет индекс сик по всем условиям.
|
|||
96
H A D G E H O G s
18.06.14
✎
15:11
|
(94) Ключ один физически, состоит из 2-х частей логически. Я же привел пример со структурой
[50,100] |
|||
97
MrStomak
18.06.14
✎
15:11
|
(92) Не рассматривай а и б как разные ключи. Это один ключ, и он отсортирован.
|
99 |
||
98
H A D G E H O G s
18.06.14
✎
15:12
|
50 - серединка диапазона [0..100] для поля a
100 - серединка диапазона [0..200] для поля b |
100 |
||
99
H A D G E H O G s
18.06.14
✎
15:13
|
(97) Тоесть, в корневом узле, значение ключа не [50,100] ?
|
101 |
||
100
MrStomak
18.06.14
✎
15:13
|
(98) нету отдельного диапазона для поля б
|
103 |
||
101
MrStomak
18.06.14
✎
15:14
|
(99) Наверху дерева первое значение, то есть 0,100
|
105 |
||
102
MrStomak
18.06.14
✎
15:15
|
дальше узлы нормализованно распределяются
|
|||
103
H A D G E H O G s
18.06.14
✎
15:15
|
(100) При построении индекса - строится побайтовая конкатенация, сортируется, выбирается середина, ее значение записывается в структуру ключа корневого узла?
|
107 |
||
104
MrStomak
18.06.14
✎
15:15
|
при этом вторая часть ключа нам бесполезна
|
|||
105
H A D G E H O G s
18.06.14
✎
15:16
|
(101) Посмотри на схемку http://commons.wikimedia.org/wiki/File:B-tree-definition.png#mediaviewer/Файл:B-tree-definition.png
Там в корневом узле - значение середины диапазона. И алгоритм поиска - именно по тому, больше или меньше искомое значение значению ключа. В зависимости от этого - идем по нужным потомкам - ветвям. |
106 |
||
106
MrStomak
18.06.14
✎
15:20
|
(105) ты прав, там середина будет.
|
107 |
||
107
H A D G E H O G s
18.06.14
✎
15:20
|
||||
108
MrStomak
18.06.14
✎
15:20
|
Ну и середина эта определяется как среденее значение сконкатенированного ключа.
|
110 |
||
109
MrStomak
18.06.14
✎
15:21
|
Да
|
|||
110
H A D G E H O G s
18.06.14
✎
15:21
|
(108) Среднее значение или значение середины диапазона?
|
|||
111
MrStomak
18.06.14
✎
15:22
|
(1068) Запись за номером N/2 в отсортированном массиве, где N- число разных ключей.
|
113 114 |
||
112
MrStomak
18.06.14
✎
15:23
|
Даже не разных, есть варианты неуникального индекса наверное.
|
|||
113
H A D G E H O G s
18.06.14
✎
15:24
|
(111) т.е. Значение середины диапазона. Ок.
|
|||
114
H A D G E H O G s
18.06.14
✎
15:24
|
(111) Вот теперь все ясно.
|
|||
115
H A D G E H O G s
18.06.14
✎
15:24
|
Вот теперь понятен смысл последующего indexscan по b>100 после indexseek по a>100
|
|||
116
MrStomak
18.06.14
✎
15:25
|
т.е. в корневом узле значение 50,100 может получиться при равномерном рампределении, т.е. одному ключу а соответствует уникальный ключ б.
|
118 |
||
117
H A D G E H O G s
18.06.14
✎
15:25
|
Я думал, дерево отсортировано по значениям полей a и b, а не по их побайтовой конкатенации.
|
119 |
||
118
MrStomak
18.06.14
✎
15:26
|
(116) Или там у тебя б=100 это начало диапазона.. Такое уже будет от везения зависеть.
|
121 |
||
119
MrStomak
18.06.14
✎
15:28
|
(117) Ну так ты спросил вроде бы для этого - одно или несколько деревьев? Нельзя отсортировать один ключ двумя способами.
|
120 122 |
||
120
MrStomak
18.06.14
✎
15:28
|
(119) Точнее, в один момент времени он будет отсортирован только одним образом.
|
|||
121
H A D G E H O G s
18.06.14
✎
15:28
|
(118) Это очень редкий шанс для больших таблиц.
|
|||
122
H A D G E H O G s
18.06.14
✎
15:30
|
(119) Я вообще не знал про физику хранения составных индексов.
|
|||
123
Кир Пластелинин
18.06.14
✎
15:36
|
мне кажется автор темы сейчас очень грустно на нее смотрит) ну и да - закладка.
|
|||
124
H A D G E H O G s
18.06.14
✎
15:44
|
||||
125
Bober
18.06.14
✎
15:56
|
(0) самый лучший вариант оптимизации это не выгребать в запросе поле версия объекта.
|
126 |
||
126
H A D G E H O G s
18.06.14
✎
16:01
|
(125) Он и не выгребает.
|
128 |
||
127
H A D G E H O G s
18.06.14
✎
16:01
|
1С не тупее паровоза.
|
|||
128
Bober
18.06.14
✎
16:02
|
(126) а это тогда кто ВерсииОбъектов.ВерсияОбъекта
|
129 |
||
129
H A D G E H O G s
18.06.14
✎
16:11
|
(128) Это будет потом, скорее всего, при Хранилище.Получить().
|
131 |
||
130
Bober
18.06.14
✎
16:12
|
||||
131
Bober
18.06.14
✎
16:12
|
(129) это идет сразу, если через запрос, то сервер 1с все это выгребает и преобразовывает с свои объекты.
|
132 |
||
132
H A D G E H O G s
18.06.14
✎
16:22
|
(131) Да, ты прав, не заметил это поле в профайлере.
|
|||
133
H A D G E H O G s
18.06.14
✎
16:22
|
Но как бы, скорее всего, это то и нужно автору.
|
134 |
||
134
Bober
18.06.14
✎
16:30
|
(133) если идет обработка в цикле версий, то скорее всего это сервисная обработка и вопрос скорости выполнения не стоял. Скорее всего это какой-то отчет или еще что-то.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |