powered by simpleCommunicator - 2.0.37     © 2025 Programmizd 02
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / SQL индекс по элементам массива
8 сообщений из 8, страница 1 из 1
SQL индекс по элементам массива
    #38904765
Petr0vi4444
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Класс event содержит список объектов класса user и индекс по ELEMENTS.
Класс userClass User.user Extends %Persistent [ SqlTableName = UserTable ]
{

Index uniqueIdx On name [ IdKey, PrimaryKey, Unique ];

Property name As %String [ ReadOnly ];

Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{
  Set i%name = $G(name)
  Quit $$$OK
}

ClassMethod get(name As %String) As %String
{
  Quit:..uniqueIdxExists(name) name
  Set obj = ..%New(name)
  If $IsObject(obj) {
    Set sc = obj.%Save()
    Quit:$$$ISOK(sc) obj.%Id()
  }
  Quit ""
}

}
Класс eventClass User.event Extends (%Persistent, %Populate)
{

Index usersIdx On users(ELEMENTS);

Property name As %String(POPSPEC = "City()");

Property users As list Of User.user(POPSPEC = "##class(User.user).get(##class(%PopulateUtils).Name()):100:Integer(1,100)");

}
Зная user.%Id() необходимо найти event.name:SELECT %NOLOCK name
FROM event
WHERE FOR SOME %ELEMENT(users) (%VALUE = 'Sorenson,Stavros P.')План запроса (относительная стоимость = 1232):
Код: xml
1.
2.
3.
4.
Read index map SQLUser.event.usersIdx, using the given %EXACT(Subvalue(users)), and looping on ID.
For each row:
    Read master map SQLUser.event.IDKEY, using the given idkey value.
    Output the row.

Индекс используется, всё работает быстро.
Переделаем users в массив.
Класс event2Class User.event2 Extends (%Persistent, %Populate)
{

Index usersIdx On users(ELEMENTS);

Property name As %String(POPSPEC = "City()");

Property users As array Of User.user(POPSPEC = "##class(User.user).get(##class(%PopulateUtils).Name()):100:Integer(1,100)");

}
Зная user.%Id() необходимо найти event.name и ключ в массиве, по которому записан user.
Т.к. users это массив, поля users в таблице event2 нет, зато есть таблица event2_users:SELECT %NOLOCK event2->name, element_key
FROM event2_users
WHERE users = 'Sorenson,Stavros P.'План запроса (относительная стоимость = 49132):
Код: xml
1.
2.
3.
4.
Read master map SQLUser.event2_users.IDKEY, looping on event2 and element_key.
For each row:
    Read master map SQLUser.event2.IDKEY, using the given idkey value, generating a row padded with nulls if none found.
    Output the row.

Индекс не используется. Объявить индекс для таблицы event2_users возможности нет.
Единственное что мне удалось придумать, это костыль вызов SqlProc:ClassMethod getEventsByUser(user As %String) As %List [ SqlName = GetEvents, SqlProc ]
{
  Set result = ""
  Set key = $O(^User.event2I("usersIdx",user,""))
  While key'="" {
    Set result = result_$LB(key)
    Set key = $O(^User.event2I("usersIdx",user,key))
  }
  Quit result
}SELECT %NOLOCK event2->name, element_key
FROM event2_users
WHERE users = 'Sorenson,Stavros P.'
AND u.event2 %INLIST GetEvents('Sorenson,Stavros P.')План запроса (относительная стоимость = 733.28):
Код: xml
1.
2.
3.
4.
Read master map SQLUser.event2_users.IDKEY, looping on event2 (with a given set of values) and element_key.
For each row:
    Read master map SQLUser.event2.IDKEY, using the given idkey value, generating a row padded with nulls if none found.
    Output the row.


Как должен выглядеть SQL запрос к таблице events2, который будет использовать индекс usersIdx?
...
Рейтинг: 0 / 0
SQL индекс по элементам массива
    #38904815
eduard93
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xml с классами, do ##class(User.user).RepopulateAll(100) для генерации данных.
...
Рейтинг: 0 / 0
SQL индекс по элементам массива
    #38905662
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
eduard93 , Спасибо за "всё в одном файле", но стоило указать, что это всё-таки не код решения, а то многие проходят мимо, думая, что вопрос исчерпан. Кстати, строка do ##class(User.user).Populate(count) - лишняя. Petr0vi4444 , Много кода оформляйте в проект в один файл и желательно полностью готовый пример. Берите пример с eduard93.
  • замените в классе User.event2
  • Index usersIdx On users(ELEMENTS); на Index usersIdx On (users(ELEMENTS), users(KEYS)); и перестройте индекс или сделайте в нём рефакторинг:Class User.event2 Extends (%Persistent, %Populate) { Index usersIdx On (users(ELEMENTS), users(KEYS)); // Property name As %String(POPSPEC = "City()"); Property users As array Of User.user(POPSPEC = "##class(User.user).get(##class(%PopulateUtils).Name()):100:City()"); }И запрос в таком случае несколько упрощается:SELECT %NOLOCK element_key name FROM event2_users WHERE users = 'Sorenson,Stavros P.'
...
Рейтинг: 0 / 0
SQL индекс по элементам массива
    #38905958
Petr0vi4444
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
servit,

Спасибо, такое решение подходит. Правда получается, что данные хранятся дважды (>_<).
...
Рейтинг: 0 / 0
SQL индекс по элементам массива
    #38906025
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petr0vi4444Правда получается, что данные хранятся дваждыКакие именно и как смотрите: по таблице или по глобалам?
...
Рейтинг: 0 / 0
SQL индекс по элементам массива
    #38906233
Petr0vi4444
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
servit,

По глобалам. Event2 хранит
^(eventid,"users",key,userid),
а в индексе тоже самое в другом порядке ключей:
^("usersidx",userid,key,eventid).
...
Рейтинг: 0 / 0
SQL индекс по элементам массива
    #38906336
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petr0vi4444 ,

Индексы - они такие, т.е. всегда избыточны, если только данные не хранить исключительно в них ( пример ).

Если хотите сэкономить, используйте отношения : parent-children или one-many:
parent-childrenClass User.p Extends (%Persistent, %Populate)
{

Index uniqueIdx On name [ IdKey, PrimaryKey, Unique ];

Property name As %String(POPSPEC = "City()");

Relationship children As User.c [ Cardinality = children, Inverse = parent ];

}

Class User.c Extends (%Persistent, %Populate)
{

Index usersIdx On users;

Property users As %String(POPSPEC = "##class(User.user).get(##class(%PopulateUtils).Name())");

Relationship parent As User.p [ Cardinality = parent, Inverse = children ];

}

SELECT %NOLOCK parent->name FROM c WHERE users = 'Sorenson,Stavros P.'
one-manyClass User.main Extends (%Persistent, %Populate)
{

Index uniqueIdx On name [ IdKey, PrimaryKey, Unique ];

Property name As %String(POPSPEC = "City()");

Relationship many As User.many [ Cardinality = many, Inverse = main ];

}

Class User.many Extends (%Persistent, %Populate)
{

Index usersIdx On users;

Property users As %String(POPSPEC = "##class(User.user).get(##class(%PopulateUtils).Name())");

Relationship main As User.main [ Cardinality = one, Inverse = many ];

}

SELECT %NOLOCK main->name FROM many WHERE users = 'Sorenson,Stavros P.'
...
Рейтинг: 0 / 0
SQL индекс по элементам массива
    #38911135
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petr0vi4444Спасибо, такое решение подходит. Правда получается, что данные хранятся дваждыЕсть решение получше .
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / SQL индекс по элементам массива
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]