powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Медленно исполняющийся запрос
11 сообщений из 11, страница 1 из 1
Медленно исполняющийся запрос
    #35389472
Hisbreht Victor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Имеем примерно следующую ситуацию.
1. Классы
Items с полем Name - некое динамически пополняемое и очищаемое хранилище, несколько сотен тысяч записей.
Items1 c полями Id,Name,Param,Parent - древовидный справочник, несколько тысяч записей.
Items2 c полями Name, Item1Id - линейный справочник, под миллион записей, динамически пополняемый.
ItemsToItems2 с полями ItemId и Item2Id - класс, обеспечивающий отношение многие ко многим для хранилища Items и справочника Items2

Запрос, выдающий для каждого элемента справочника Items1 количество записей в хранилище, которые имеют связь через объекты класса ItemsToItems2 со справочником Items2,которые, в свою очередь, связаны с соответствующим элементом справочника Items1
SELECT Id AS Item1Id,Parent AS pId, Param,Name,
(SELECT COUNT(DISTINCT ItemId) FROM ItemsToItems2
WHERE Item2Id->Item1Id=Items1.ID) AS ItemsCount
FROM Items1 ORDER BY Param.

Запрос выполняется около минуты, что есть много.

Какие меры можно принять для ускорения запроса, как его оптимизировать, какие индексы нарисовать?

Что любопытно, при некоторых вариантах выбора поля и направления сортировки (ORDER BY Param DESC) запрос выполняется за пару секунд (жаль, что не всегда нужна именно такая сортировка, точнее она совсем никогда не нужна).

Можно было бы, конечно, при записи в Items увеличивать какой-нибудь счетчик для Items1, но на запрос могут быть наложены дополнительные условия, а на все варианты условий счетчиков не напасешься.
...
Рейтинг: 0 / 0
Медленно исполняющийся запрос
    #35389767
=Dimon=
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте!
Во-первых, можно создать вычислимое (Calculated) поле в Items1 которое бы вернуло количество записей из ItemsToItems2
Во-вторых, можно использовать глобалы и при операции Insert/Delete/Update записывать количество записей для конкретной группы. Поле Calculated сразу бы возвращало из глобала значение.
В-третьих можно грамотно использовать индексы, построить индекс на таблицу ItemsToItems2 по полю Item2Id

P.S. 2 метод этот модифицированный 1 метод.
...
Рейтинг: 0 / 0
Медленно исполняющийся запрос
    #35390329
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1) $SYSTEM.SQL.TuneTable;
2) Для ускорения соединений рекомендую на все Relationship поставить индекс;
3) Для ускорения в частности count рекомендую bitmap -индекс;
4) В индексе можно хранить некоторые данные, например Param для order by ;
5) Смотрите план запроса и его стоимость в SMP: [Домашняя страница] > [SQL] > [Исполнить SQL запрос].

PS: еще можете воспользоваться материалами DevCon 2008 , например, Understanding and Optimizing SQL Performance
...
Рейтинг: 0 / 0
Медленно исполняющийся запрос
    #35421610
Hisbreht Victor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что-то производительность Cache' не радует.
Есть класс, состоящий из ссылок на классы-справочники и нескольких текстовых полей, полмиллиона записей.
Если запрос выдать без сортировки, первая запись появляется практически мгновенно.
Если добавить правило ORDER BY по любому полю (по всем созданы индексы, по справочникам - bitmap), то время выдачи первой записи колеблется от 5 до 15 секунд.
Что еще можно сделать для ускорения, учитывая, что размер таблицы быстро изменяется и может быть в пределах от нуля до нескольких миллионов записей, а разные запросы могут выдавать разную долю этих записей (т.е. установка для класса значений количества записей и доли записей, возвращаемых типовым запросом вроде как бессмысленна)?
...
Рейтинг: 0 / 0
Медленно исполняющийся запрос
    #35422010
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hisbreht Victor , где тестовый пример? Без примера как отвечать на твои вопросы?
----------
Cache for Windows (x86-32) 2007.1.3 (Build 607) Wed Oct 17 2007 02:12:09 EDT
...
Рейтинг: 0 / 0
Медленно исполняющийся запрос
    #35423175
CJIECAPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Для запроса из первого поста создал соответствующие таблички:
Items - 500000 записей
Items1 - 50000 записей
Items2 - 850000 записей
ItemsToItems2 - 1100000 записей

В Items2 индекс
Код: plaintext
1.
Index NewIndex1 On Item1Id;

В ItemsToItems2 индекс
Код: plaintext
1.
Index NewIndex1 On Item2Id;

Приведённый запрос выполнился за 34 секунды

Изменил индекс в ItemsToItems2 на
Код: plaintext
1.
Index NewIndex1 On Item2Id [ Data = ItemId ];

Запрос выполнился за 26 секунд

Добавил в ItemsToItems2 вычислимое поле и индекс по нему:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Property Item1Id As Items1 [ Calculated, SqlComputeCode = {	S {Item1Id}=##class(Items2).%OpenId({Item2Id}).Item1IdGetObjectId()}, SqlComputed ];

Method Item1IdGet() As Items1
{
	Q:($ISOBJECT(..Item2Id)) ..Item2Id.Item1Id
	Q $$$NULLOREF
}

Изменил запрос:
Код: plaintext
1.
2.
3.
SELECT Id AS Item1Id,Parent AS pId, Param,Name,
(SELECT COUNT(DISTINCT ItemId) FROM ItemsToItems2 WHERE Item1Id=Items1.ID) AS ItemsCount
FROM Items1 ORDER BY Param

Время выполнения: 17 секунд

Время засекалось от создания %ResultSet до окончания пустого цикла WHILE rs.Next() {}
...
Рейтинг: 0 / 0
Медленно исполняющийся запрос
    #35423414
CJIECAPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если и это сильно много, можно сделать так:

Добавляем индекс в ItemsToItems2
Код: plaintext
1.
Index NewIndex3 On (Item1Id, ItemId) [ Type = bitmap ];

А в Items1 создаём хранимую процедуру
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
ClassMethod CountDisctinctItem(Item1Id As %String) As %Integer [ SqlProc ]
{
	S res= 0 
	S key=""
	F {
		S key=$O(^User.ItemsToItems2I("NewIndex3",Item1Id,key))
		Q:(key="")
		S res=res+ 1 
	}
	Q res
}

Теперь запрос принимает вид
Код: plaintext
1.
2.
SELECT Id AS Item1Id,Parent AS pId, Param,Name, Items1_CountDisctinctItem(ID) AS ItemsCount
FROM Items1 ORDER BY Param
и выполняется за 4.5 секунды.
...
Рейтинг: 0 / 0
Медленно исполняющийся запрос
    #35425017
Hisbreht Victor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CJIECAPb
Добавил в ItemsToItems2 вычислимое поле и индекс по нему:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Property Item1Id As Items1 [ Calculated, SqlComputeCode = {	S {Item1Id}=##class(Items2).%OpenId({Item2Id}).Item1IdGetObjectId()}, SqlComputed ];

Method Item1IdGet() As Items1
{
	Q:($ISOBJECT(..Item2Id)) ..Item2Id.Item1Id
	Q $$$NULLOREF
}
Что-то я не понял, откуда взялось это - Item1IdGetObjectId.
На приведенный код Cache, естественно, ругается, что такого метода нет.
Что тут имелось ввиду?
...
Рейтинг: 0 / 0
Медленно исполняющийся запрос
    #35425209
CJIECAPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hisbreht Victor CJIECAPb
Добавил в ItemsToItems2 вычислимое поле и индекс по нему:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
Property Item1Id As Items1 [ Calculated, SqlComputeCode = {	S {Item1Id}=##class(Items2).%OpenId({Item2Id}).Item1IdGetObjectId()}, SqlComputed ];

Method Item1IdGet() As Items1
{
	Q:($ISOBJECT(..Item2Id)) ..Item2Id.Item1Id
	Q $$$NULLOREF
}
Что-то я не понял, откуда взялось это - Item1IdGetObjectId.
На приведенный код Cache, естественно, ругается, что такого метода нет.
Что тут имелось ввиду?
Хм. У меня работает. У вас какая версия каше?
В классе Item2Id поле Item1Id какой тип имеет? Если %String - замените на Items1.
В ##class(Items2) параметра SqlComputeCode пропишите полное имя класса (если пакет по умолчанию User, то ##class(User.Items2))
...
Рейтинг: 0 / 0
Медленно исполняющийся запрос
    #35426460
Hisbreht Victor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CJIECAPbХм. У меня работает. У вас какая версия каше?
В классе Item2Id поле Item1Id какой тип имеет? Если %String - замените на Items1.
В ##class(Items2) параметра SqlComputeCode пропишите полное имя класса (если пакет по умолчанию User, то ##class(User.Items2))В общих чертах заработало, просто немного ошибся при копировании текста, но возникла другая проблема,
условие запроса WHERE Item1Id=Items1.ID возвращает всегда "ложь". Почему это может быть?
При отборе Item1Id видно, какие он принимает значения. Такой объект в Items1 есть, но сравнение всегда ложно. И так любая операция сравнения кроме !=, которая всегда возвращает "истина".
С чем это может быть связано, где я опять мог ошибиться?
Бился как пчелка об мед, но пока не понял, что бы это значило.
...
Рейтинг: 0 / 0
Медленно исполняющийся запрос
    #35427558
CJIECAPb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Hisbreht Victor CJIECAPbХм. У меня работает. У вас какая версия каше?
В классе Item2Id поле Item1Id какой тип имеет? Если %String - замените на Items1.
В ##class(Items2) параметра SqlComputeCode пропишите полное имя класса (если пакет по умолчанию User, то ##class(User.Items2))В общих чертах заработало, просто немного ошибся при копировании текста, но возникла другая проблема,
условие запроса WHERE Item1Id=Items1.ID возвращает всегда "ложь". Почему это может быть?
При отборе Item1Id видно, какие он принимает значения. Такой объект в Items1 есть, но сравнение всегда ложно. И так любая операция сравнения кроме !=, которая всегда возвращает "истина".
С чем это может быть связано, где я опять мог ошибиться?
Бился как пчелка об мед, но пока не понял, что бы это значило.
Если
Код: plaintext
1.
select top  20  Item1Id, Item2Id->Item1Id from ItemsToItems2
отрабатывает правильно, то скорее всего у вас просто не перестроен индекс NewIndex3
Выполни
Код: plaintext
1.
2.
d ##class(ItemsToItems2).%PurgeIndices()
d ##class(ItemsToItems2).%BuildIndices()
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Медленно исполняющийся запрос
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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