![]() |
#1 |
Участник
|
Зачем нужен уникальный index, содержащий RecId?
На некотроых таблицах уровня SYS наблюдается наличие уникального индекса в состав, которого по мимо прочих полей входит поле RecId (например индекс ItemIdx на таблице InventItemBarcode). Известно что если не включать RecId в индекс и не делать его уникальным, то система по умолчанию на уровне БД сама создаст его (Проблема с индексами).
Отсюда вопрос. Какой смысл вручную создавать такой абсурдный с точки зрения приложения индекс (уникальность RecId - это всё же забота ядра и БД). И не в этом ли кроются ошибки, такие как Существуют аргументы, почему неуникальность баркода у номенклатуры не является багой? Т.е. на мой взгляд, уникальные индексы необходимы для ограничения дубликатов строк, а какой в них толк, если они содержат поле RecID, уникальное априори? Следовательно либо требование уникальности здесь избыточно, либо наличие в уникальном индексе поля RecId является ошибкой проектирования, вызванной попыткой уменьшить число индексов на таблице. |
|
![]() |
#2 |
MCITP
|
![]() Цитата:
Сообщение от S.Kuskov
![]() На некотроых таблицах уровня SYS наблюдается наличие уникального индекса в состав, которого по мимо прочих полей входит поле RecId (например индекс ItemIdx на таблице InventItemBarcode). Известно что если не включать RecId в индекс и не делать его уникальным, то система по умолчанию на уровне БД сама создаст его (Проблема с индексами).
Отсюда вопрос. Какой смысл вручную создавать такой абсурдный с точки зрения приложения индекс (уникальность RecId - это всё же забота ядра и БД). И не в этом ли кроются ошибки, такие как Существуют аргументы, почему неуникальность баркода у номенклатуры не является багой? Т.е. на мой взгляд, уникальные индексы необходимы для ограничения дубликатов строк, а какой в них толк, если они содержат поле RecID, уникальное априори? Следовательно либо требование уникальности здесь избыточно, либо наличие в уникальном индексе поля RecId является ошибкой проектирования, вызванной попыткой уменьшить число индексов на таблице. Вы же сами ответили на свой вопрос... ![]() Здесь уже писал об алгоритме: Не выделять RecId Т.е. это добавление идёт только в случае когда в таблице нет вообще индексов уникальных.. А уникальный индекс Аксапте нужен... Например для работы .reread()... ![]()
__________________
Zhirenkov Vitaly |
|
![]() |
#3 |
Moderator
|
К слову сказать - для производительности SQL-сервера (и MS SQL и Oracle) выгоднее индексы с более высокой селективностью (в идеале - уникальные). В тех случаях, когда системе нужно по значению клуча найти нужную запись в индексе (например - при удалении записи в таблице), система, в первом приближении, перебирает все записи с данным ключем, до тех пор пока не найдет ту запись у которой физический адрес записи в таблице совпадает с необходимым. Поэтому если у таблицы много неуникальных индексов с малой селективностью (порядка сотен записей с одинаковым ключем), обновление начинает подтормаживать. В таких случаях можно довольно заметно ускорить работу с таблицей, преобразовав часть подобных индексов в уникальные. Некоторое увеличение индекса и времени поиска по индексу из за хранения лишнего поля, с лихвой компенсируется заметным уменьшением времени обновления.
Ну и как уже написали предыдущие ораторы - для работы системы кэширования аксаптовской, система должна иметь хотя бы один уникальный индекс. |
|
![]() |
#4 |
MCITP
|
![]() Цитата:
Сообщение от fed
![]() В тех случаях, когда системе нужно по значению клуча найти нужную запись в индексе (например - при удалении записи в таблице), система, в первом приближении, перебирает все записи с данным ключем, до тех пор пока не найдет ту запись у которой физический адрес записи в таблице совпадает с необходимым. Поэтому если у таблицы много неуникальных индексов с малой селективностью (порядка сотен записей с одинаковым ключем), обновление начинает подтормаживать.
![]() Или это было о том как теоретически могло бы быть? ![]()
__________________
Zhirenkov Vitaly |
|
![]() |
#5 |
Участник
|
Еще есть такой прием (в одной книжке по ораклу вычитал) как overindexing - в индекс добавляется поле, которое нужно выбирать при выборке по индексу. Таким образом не нужна операция по подъему из базы страниц с данными - значение берется из индекса.
то есть если будет запрос X++: select recID from T where T.ItemID = 'z' |
|
![]() |
#6 |
MCITP
|
![]() Цитата:
Сообщение от belugin
![]() Еще есть такой прием (в одной книжке по ораклу вычитал) как overindexing - в индекс добавляется поле, которое нужно выбирать при выборке по индексу. Таким образом не нужна операция по подъему из базы страниц с данными - значение берется из индекса.
то есть если будет запрос X++: select recID from T where T.ItemID = 'z' ![]() Но подход да, стар как мир - оптимизатор позволяет исключить обращение к таблице, если все данные есть в индексе. ![]() Кстати в SQL2005 есть новая фича, называется "Included columns", тоже на эту тему... Правда вот Аксапте это вряд ли поможет ![]()
__________________
Zhirenkov Vitaly |
|
![]() |
#7 |
Участник
|
|
|
![]() |
#8 |
Moderator
|
Цитата:
Сообщение от ZVV
![]() Аксапта, насколько я знаю, так не работает (перебирает неуникальные индексы) по указанной выше причине - всегда есть уникальный индекс и она его использует.
![]() Или это было о том как теоретически могло бы быть? ![]() Насколько я знаю - некоторые БД пытались решить эту проблему за счет того, что индекс подспудно сортировался по сочетанию ключ+физический адрес записи (ROW_ID). (То есть - значение ссылки на запись становилась некой виртуальной частью ключа). Однако - на практике это приводило к изрядным проблемам, поскольку приводило к усиленной перебалансировке дерева страниц при вставке новых записей. Кроме того - при реорганизации и упаковке таблиц, это усложняло перестроение индексов. Так что - насколько я понимаю, в текущих версиях и SQL Server и Oracle используется именно такой подход к удалению ключей, который я описал... |
|
|
За это сообщение автора поблагодарили: Logger (1), Kabardian (4). |
![]() |
#9 |
Участник
|
Возможно я что-то путаю, но разве авотматическое добаление RecId в индекс не ограничивается лишь уровенем БД? В смысле меняется ли автоматически индекс и в самом приложении (АОТ)? Если меняется, то в какой момент? при сохранении таблицы? при синхронизации?
|
|
![]() |
#10 |
Участник
|
И ещё возник такой вопрос. Если уникальность RecId контролируется составным индексом, где помимо RecId присутствуют ещё и другие поля, то уникальность отдельно самого поля RecId, вообще говоря, уже не обеспечивается. Не является ли это потенциальным источником ошибок?
|
|
![]() |
#11 |
Moderator
|
Цитата:
Насколько я знаю - некоторые БД пытались решить эту проблему за счет того, что индекс подспудно сортировался по сочетанию ключ+физический адрес записи (ROW_ID). (То есть - значение ссылки на запись становилась некой виртуальной частью ключа). Однако - на практике это приводило к изрядным проблемам, поскольку приводило к усиленной перебалансировке дерева страниц при вставке новых записей. Кроме того - при реорганизации и упаковке таблиц, это усложняло перестроение индексов.
Так что - насколько я понимаю, в текущих версиях и SQL Server и Oracle используется именно такой подход к удалению ключей, который я описал... Правда для того, чтобы Аксапта создавала такие индексы ее придется слегка допилить. |
|
![]() |
#12 |
Moderator
|
Цитата:
Еще есть такой прием (в одной книжке по ораклу вычитал) как overindexing - в индекс добавляется поле, которое нужно выбирать при выборке по индексу.
|
|
![]() |
#13 |
MCITP
|
![]()
petr, fed -- теперь я понял о чём вы, это всё понятно и верно, но непонятно какое отношение к исходному вопросу?
__________________
Zhirenkov Vitaly |
|
![]() |
#14 |
MCITP
|
![]() Цитата:
можете попробовать сами: на таблице с индексом по Field1 (неуникальным) в случае .update() на БД уйдёт запрос вида: X++: UPDATE TABLE2 SET FIELD1=?,RECVERSION=? WHERE ((((DATAAREAID=?) AND (FIELD1=?)) AND (RECID=?)) AND (RECVERSION=?)) Цитата:
![]()
__________________
Zhirenkov Vitaly |
|
![]() |
#15 |
Участник
|
Цитата:
![]() Второе - в AX директива index в запросе не игнорируется и записи сортируются в порядке полей индекса. Цитата:
P.S. Насколько мне известно термин "overindexing" означает "перегруженность" таблицы индексами
__________________
Sergey Nefedov Последний раз редактировалось SRF; 30.07.2009 в 21:22. |
|
![]() |
#16 |
Участник
|
|
|
![]() |
#17 |
Ищущий знания...
|
Цитата:
![]()
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем Последний раз редактировалось mazzy; 05.11.2013 в 15:33. |
|
![]() |
#18 |
MCITP
|
![]()
Редко такое встречали говорите...
![]() Было бы интересно взглянуть хоть на одного... ![]() Включение потабличного RecID в 3-ке
__________________
Zhirenkov Vitaly Последний раз редактировалось ZVV; 30.07.2009 в 23:13. |
|
![]() |
#19 |
Moderator
|
Цитата:
Топикстартер спрашивает - зачем создавать индексы с фиктивной уникальностью, добавляя поле recid, если в соответствии с информацией из сообщения Проблема с индексами система сама добавляет поле recId в первый попавшийся индекс и делает его уникальным ?Отвечаем: Я тут долго рассуждал что уникальность индекса хороша не только потому что она позволяет избежать дубликатов, но и потому что она упрощает обновление индекса и таблицы. Встроенный механизм добавляет поле recId во первых к первому попавшемуся индексу, во вторых только к одному индексу. Для повышения производительности полезно добавлять уникальное поле во все индексы с малой селективностью, а не только в первый попавшийся. Ну и гипотеза насчет coverage index тоже весьма правдоподобна. Таким образом - ручное добавление recId в конец некоторых индексов вызвано не необходимостью отслеживания уникальности, а возможностью повысить производительность работы сервера БД с данным индексом. |
|
|
За это сообщение автора поблагодарили: mazzy (2), ZVV (2), S.Kuskov (1). |
![]() |
#20 |
Moderator
|
Цитата:
Сообщение от Андре
![]() Насколько я помню, Oracle в таких случаях предлагает использовать bitmap-индексы (индексы на основе битовых карт - не уверен в переводе), которые по своей сути не являются деревьями и решают обозначенную тобой проблему.
Правда для того, чтобы Аксапта создавала такие индексы ее придется слегка допилить. |
|
Теги |
index, indexunique, recid, индекс |
|
|