v8: Опять использование индексов #660457


#0 by H A D G E H O G s
Простейший запрос: ВЫБРАТЬ    РеализацияТоваровУслугТовары.Ссылка.Организация,    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары    РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрганизаций 2 запрос дает Clustered Index Scan по индексу: _Accum20481_ByPeriod_TRN, хотя в него не входит ни СерияНоменклатуры ни Организация из регистра накопления. Как так?! Вот план запроса: StmtText     Hash Match(Right Semi Join, HASH:([T2].[_Q_000_F_000RRef], [T2].[_Q_000_F_001RRef])=([T1].[_Fld20482RRef], [T1].[_Fld20486RRef]), RESIDUAL:([Database].[dbo].[_AccumRg20481].[_Fld20482RRef] as [T1].[_Fld20482RRef]=[tempdb].[dbo].[#tt2].[_Q_000_F_000RRef] as [T2].[_Q_000_F_000RRef] AND [Database].[dbo].[_AccumRg20481].[_Fld20486RRef] as [T1].[_Fld20486RRef]=[tempdb].[dbo].[#tt2].[_Q_000_F_001RRef] as [T2].[_Q_000_F_001RRef]))
#0 by H A D G E H O G s
Простейший запрос: ВЫБРАТЬ    РеализацияТоваровУслугТовары.Ссылка.Организация,    Документ.РеализацияТоваровУслуг.Товары КАК РеализацияТоваровУслугТовары    РегистрНакопления.ТоварыОрганизаций КАК ТоварыОрганизаций 2 запрос дает Clustered Index Scan по индексу: _Accum20481_ByPeriod_TRN, хотя в него не входит ни СерияНоменклатуры ни Организация из регистра накопления. Как так?! Вот план запроса: StmtText     Hash Match(Right Semi Join, HASH:([T2].[_Q_000_F_000RRef], [T2].[_Q_000_F_001RRef])=([T1].[_Fld20482RRef], [T1].[_Fld20486RRef]), RESIDUAL:([Database].[dbo].[_AccumRg20481].[_Fld20482RRef] as [T1].[_Fld20482RRef]=[tempdb].[dbo].[#tt2].[_Q_000_F_000RRef] as [T2].[_Q_000_F_000RRef] AND [Database].[dbo].[_AccumRg20481].[_Fld20486RRef] as [T1].[_Fld20486RRef]=[tempdb].[dbo].[#tt2].[_Q_000_F_001RRef] as [T2].[_Q_000_F_001RRef]))
#1 by Fragster
ты посмотри, во что (1,2) в (Выбрать 1,2 из ВТ) превращается...
#2 by Fragster
там трэш
#3 by H A D G E H O G s
Какая разница?
#4 by H A D G E H O G s
exec sp_executesql N'SELECT FROM _AccumRg20481 T1 WITH(NOLOCK) WHERE EXISTS(SELECT 1 FROM #tt2 T2 WITH(NOLOCK) WHERE (T1._Fld20482RRef = T2._Q_000_F_000RRef) AND (T1._Fld20486RRef = T2._Q_000_F_001RRef))',N' numeric',1
#5 by rs_trade
хех, надо на 18 релизе глянуть. они же написали что наоптимизировали чего то там.
#6 by H A D G E H O G s
какая разница, какой релиз. Речь про SQL
#7 by Fragster
ты чуешь коррелированный запрос
#8 by H A D G E H O G s
Я даже слова такого не знаю.
#9 by acsent
кластеред индекс скан = тэйбл скан
#10 by Fragster
короче, замени на внутреннее соединение
#11 by H A D G E H O G s
Счегобы?
#12 by acsent
в данном случае это быстрее
#13 by acsent
индекс содержит все измерения
#14 by H A D G E H O G s
Нет
#15 by acsent
ведь скан, а не сиик
#16 by H A D G E H O G s
Именно это и удивляет.
#17 by H A D G E H O G s
Скан индекса, а не таблицы.
#18 by acsent
как это не содержит, врешь
#19 by fisher
Да, прикольно... Может, оптимизатор запросов БД не обращает внимания на выбираемые поля?
#20 by H A D G E H O G s
Период, Регистратор, НомерСтроки
#21 by acsent
Да не поэтому, а потому что он КЛАСТЕРНЫЙ - это и есть физ. записи в таблицах
#22 by fisher
А порядок измерений в регистре какой? И какие измерения индексированы дополнительно?
#23 by Fragster
это для обхода коррелированного запроса, но сугубо имхо
#24 by fisher
+1
#25 by H A D G E H O G s
Нет
#26 by Fragster
не
#27 by H A D G E H O G s
В кластерном данные - сразу, но только тех полей, которые в нем.
#28 by Fragster
#29 by H A D G E H O G s
Это копия, а не ссылка.
#30 by H A D G E H O G s
Вложенные в терминологии 1С?
#31 by acsent
там exist используется
#32 by acsent
это в обычном индексе
#33 by Fragster
да, но он все равно вызывается для каждой строки внешнего запроса (т.е. таб. регистра)
#34 by acsent
Кластерный индекс, это не индекс, а физ порядок
#35 by fisher
Кластерный индекс вроде все поля содержит же. Те, по поля по которым строится - порядок определяют.
#36 by H A D G E H O G s
Четовы меня смутили. Пойду почитаю про кластерный
#37 by acsent
в случае с Exist работает быстрее чем внутреннее соединение
#38 by Fragster
эксистс - это тупо приближенно "селект топ 1"
#39 by acsent
ведь что есть внутреннее соединение - nested lookup, и вложенный тоже самое
#40 by acsent
не сомвем
#41 by fisher
Тю. Я думал, вопрос был в том, почему не используется подходящий индекс, вместо скана таблицы.
#42 by Fragster
пусть автор ответит, быстрее, или нет :)
#43 by acsent
на 2000 во времена 77 точно быстрее было. сам проверял
#44 by H A D G E H O G s
Все, извиняюсь, кластерный индекс содержит данные.
#45 by H A D G E H O G s
Но план запроса все равно это не объясняет.
#46 by acsent
и что не понятно с учетом
#47 by H A D G E H O G s
Тааааак
#48 by H A D G E H O G s
sql построил хэш по 2-м полям и давай сканировать таблицу, но сканировать упорядоченно по кластерному индексу, так?
#49 by H A D G E H O G s
момент
#50 by Fragster
вообще, конечно, не хватает возможности лепить свои составные индексы
#51 by H A D G E H O G s
Я не могу добиться TableScan-а
#52 by H A D G E H O G s
Чтобы понять
#53 by H A D G E H O G s
Как только в таблице имеется кластерный индекс, IAM более не используется для доступа к данным. IAM не исчезает вообще, но используется только для сопровождения таблицы как объекта в базе данных. Страницы данных взаимосвязаны и данные в них находятся в соответствии с кластерным индексом. Если выполнить запрос SELECT * FROM Customers без каких-либо условий WHERE, то система выполнить сканирование таблицы с использованием кластерного индекса. Эта операция очень похожа на простое сканирование таблицы. Главное различие между сканированием по кластерному индексу то, что результат сканирования вернется в порядке сортировки по кластерному индексу.
#54 by H A D G E H O G s
Все, понял, разобрался. Ascent-у респект и уважуха.
#55 by Fragster
а ?
#56 by H A D G E H O G s
Я на Exist забил.
#57 by Никола_Питерский
Тады точно SAP и другие помрут ))))
#58 by H A D G E H O G s
Вернемся к нашим песням. Смотрим типовые - на всех регистрах стоит индексированное измерение "Номенклатура", но неиндексированное "Серия". Логично. Но у меня есть регистр, который имеет измерение "Номенклатура" и "СерияНоменклатуры" (которое заполнено гораздо чаще чем в типовом случае). На данный момент индексированна "Номенклатура", но почти во всех запросах к регистру в условиях есть Номенклатура и Серия. Запросы скорее всего выполняют index seek nonclustered по индексу номенклатуры, а затем KeylookUp по физ. таблице по Серии. Если я добавлю индекс по серии - я не уверен, что оптимизатор выберет индекс по серии (но счаст попробую) и уверен, что запись будет медленней. И, как вариант - снять индекс с Номенклатуры и поставить на Серию. Что думаете?
#59 by H A D G E H O G s
Ладно, другой вопрос - почему в Типовых Серия не индексированна?
#60 by Fragster
потому что типовой механизм индексирования не дает делать нормально составные индексы
#61 by Fragster
а по алгоиртмам выбирается номенклатура + серия
#62 by H A D G E H O G s
Ну и что.
#63 by H A D G E H O G s
Вообще странно все.
#64 by H A D G E H O G s
Выбираю по серии и номенклатуре. Индексированна номенклатура - Clastered Index Scan Индексированна Серия - Index Seek+Lookup Индексированна Серия и Номенклатура - Index Seek (по индексу Серии)+Lookup
#65 by H A D G E H O G s
Почему в 1 случае SQL делает Index Scan, ведь у него индекс есть по номенклатуре!
#66 by H A D G E H O G s
Счаст попробую Первый случай, но отбирать буду только по номенклатуре, а в выборку включу Серию, Index Scan он мне сделает, или Index Seek по номенклатуре...
#67 by Fragster
1. оптимизатор решил, что использовать индекс по номенклатуре неоптимально, попробуй статистику обновить 2 и 3 - одинаково по сути, так как правильных составных индексов нету. но никто не мешает навешивать свои составные индексы (до реструктуризиции, правда)
#68 by H A D G E H O G s
Индексированна Серия. И ищем по Серии и Номенклатуре. Лишние lookup-ы будут только там, где серия пустая, зачем тут составной индекс (в индекс включать Номенклатуру).
#69 by H A D G E H O G s
?
#70 by H A D G E H O G s
Пардон, спешу добавить.... И мы не просто ищем серию  и номенклатуру, но мы еще и Количество их берем :-)
#71 by Fragster
а оптимизатор об этом знает? какой % записей с пустой?
#72 by Fragster
вообще - индексирована серия - значит составной индекс на серию, период, регистратор, номер строки.... - оптимизатор думает, что ну его нафиг, погляжу ка я всю таблицу...
#73 by H A D G E H O G s
Я не про то. Я про то, что Вот ищем мы Номенклатура       Серия Лада               Калина SQL найдет по индексу "Калина" идентификатор строки и слазит в таблицу проверить Лада это или нет. И заодно вытащит Количество. Все норм. Однозначно надо лезть в таблицу за количеством. Все норм. Вот ищем мы Номенклатура       Серия SQL найдет по индексу "ПустаяСерия" идентификатор строки и слазит в таблицу проверить Жигулиэто или нет.  А это не Жигули, а Камаз. Неудача. Тут бы составной индекс и пригодился.
#74 by H A D G E H O G s
ms sql 2008 r2 пока так не думает.
#75 by H A D G E H O G s
Просто таких пустых серий У МЕНЯ будет мало. А вот типовые конфы универсальны, учет может быть и без серий, поэтому Серия и не индексированна.
#76 by H A D G E H O G s
Или нет?
#77 by H A D G E H O G s
Clastered Index Scan, блин.
#78 by H A D G E H O G s
Серию убираю, только номенклатура в Выборке - Index Seek без Lookup-а, но это то понятно.
#79 by Fragster
сделай свой индекс ТОЛЬКО по серии, будет отбирать по нему
#80 by H A D G E H O G s
Это и работает.
#81 by H A D G E H O G s
Для Серии - работает. Для Номенклатуры - нет. Статистику - обновлял.
#82 by H A D G E H O G s
Выбираю по серии и номенклатуре. 1) Индексированна номенклатура - Clastered Index Scan 2) Индексированна Серия - Index Seek+Lookup 3) Индексированна Серия и Номенклатура - Index Seek (по индексу Серии)+Lookup 1 случай, отбирать буду только по номенклатуре, а в выборку включаю Серию. Хочу IndexSeek + Lookup, получаю Clastered Index Scan (Table Scan) по факту.
#83 by Fragster
т.е. не галочки в 1с, а именно руками созданные индексы?
#84 by H A D G E H O G s
Нет, галочки.
#85 by H A D G E H O G s
Предлагаешь создать отдельный некластерный индекс только по полю Номенклатура, в SQL ?
#86 by Fragster
галочки в 1с не рулят
#87 by Fragster
рестартани скуль, если есть возможность, и: SELECT  TOP 10 FROM        sys.dm_db_missing_index_groups g INNER JOIN    sys.dm_db_missing_index_group_stats s       ON s.group_handle = g.index_group_handle INNER JOIN    sys.dm_db_missing_index_details d       ON d.index_handle = g.index_handle ORDER BY [Total Cost] DESC;
#88 by Fragster
ну и отбор по имени таблицы
#89 by Fragster
это после пары десятков своих запросов
#90 by H A D G E H O G s
Нет возможности пока. Будет ближе к ночи.
#91 by H A D G E H O G s
СОздал чистый индекс по номенклатуре, не использует его никак, использует старый индекс с Регистратором и Периодом, и.т.д. Статистику обновил, что еще надо сделать?
#92 by H A D G E H O G s
Ооо, снесу старый :-)
#93 by H A D G E H O G s
Ооо, стал использовать Мой Индекс, когда в выборке тока номенклатура.
#94 by H A D G E H O G s
И Clastered Index Scan, когда в выборке добавляю еще и Серию, пичаль.
#95 by H A D G E H O G s
Ладно, пойду поем, а ночью, когда никто не видит, буду ставить опыты.
#96 by H A D G E H O G s
Я конечно догадываюсь, что дело в селективности, но вроде номенклатура достаточно уникальна, надо глянуть.
#97 by H A D G E H O G s
Фсе, отбой. Дело было в селективности.
#98 by H A D G E H O G s
Номенклатура была часто встречающаяся в регистре - и поэтому выбирался Index Scan, а потом уж отбор по серии - и в выборке у меня было мало записей, а когда отключил отбор по серии и тупо ее в выборке выводил - уже не обратил внимания на то, что там дофига записей.
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям