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