Задавайте вопросы, мы ответим
Вы не зашли.
В таблице Item хранится дерево. Каждый Item дерева может иметь одну или несколько версий. [Самый простой ассоциативный пример - это структура Visual SourceSafe, где у файла несколько версий.] Каждый Item имеет уникальный ID (primary key) и RealID - одинаковый для всех версий одного Item'а (то есть по сути RealID - идентификатор группы версий одного Item'а).
Задача - отобразить самый свежий срез дерева, то есть для каждого Item брать внутри его группы Item с наибольшим ID + уметь упорядочивать по заданному условию отобранные Item'ы.
Все сделано, все работает. До тех пор, пока item'ов не больше 40. После этого начинаются жуткие тормоза у хостера (пробовал трех, результат одинаковый).
Например, если развернуть ветку дерева, то посылается около 70 запросов вида:
SELECT * FROM Item WHERE ID IN (SELECT MAX(ID) FROM Item WHERE (ParentID='190' AND Removed = '0') GROUP BY RealID) ORDER BY Priority;
Получается что запрос с подзапросом + используются функции и группировка + упорядочивание. В общем, нагрузка очень и очень немалая.
Возникает вопрос: как обойтись малой кровью, сократив кол-во запросов, либо переделать данный запрос, чтобы был менее ресурсоемким.
Заранее благодарен.
Неактивен
Я предложил бы другой путь. Так как элементов немного, можно сделать
SELECT * FROM Item
а далее в языке программирования (для примера PHP) загрузить все элементы в хэши - $item_by_id, $item_by_parent (макс ID можно также за тот же один проход учесть - просто всегда замещать более новым элементом более старые), затем построить прямо структуру в виде требуемого дерева как многократно вложенный массив, или иначе. Сложность алгоритма будет линейной. На SQL расчитывать здесь не стоит, все ИМХО.
Неактивен
Спасибо, это единственное, что мне тоже пришло в голову. Сделать workaround в PHP. Но что делать, если элементов будет много? По частям селектом извлекать?
Неактивен
Если их будет настолько много, то есть десятки тысяч, то можно сделать другое усовершенствование - хранить все версии, кроме последней в другой таблице, причем заносить в нее данные триггером BEFORE UPDATE на основной таблице.
Неактивен