[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Оптимизация построения дерева из MySQL базы
Эдик
Здравствуйте! Столкнулся с очень неприятной проблемой.
В общем так. Есть в базе данных таблица, в которой хранится все дерево, те id коневой категории, id подкатегорий, id подкатегорий подкатегорий и тд. Если у родителя есть подгатегория, то значение поля ==1, если нету ==0.
/* Построение дерева категорий изделий для заданного типа автомобиля (TYP_ID) */

SET @TYP_ID = 3822; /* ALFA ROMEO 145 (930) 1.4 i.e. [1994/07-1996/12] */
SET @LNG_ID = 16; /* 1 - Немецкий язык; 16 - Русский язык */
SET @STR_ID = NULL; /* Корень дерева */
/* Последовательно устанавливая следующие значения STR_ID, можно получить ещё 4 уровня дерева: */
/* SET @STR_ID = 10001; /* Легковые автомобили */
/* SET @STR_ID = 10102; /* Двигатель */
/* SET @STR_ID = 10615; /* Кривошатунный механизм */
/* SET @STR_ID = 10620; /* Поршень */

/* Вывод списка подкатегорий для выбранной категории с номером @STR_ID,*/
/* содержащие изделия для заданного типа автомобиля (TYP_ID) */
/* STR_ID - Номер категории */
/* STR_DES_TEXT - Название категории */
/* DESCENDANTS - Есть ли у этой категории подкатегории: 1 - Есть, 0 - Нет */

SELECT
STR_ID,
TEX_TEXT AS STR_DES_TEXT,
IF(
EXISTS(
SELECT
*
FROM
SEARCH_TREE AS SEARCH_TREE2
WHERE
SEARCH_TREE2.STR_ID_PARENT <=> SEARCH_TREE.STR_ID
LIMIT
1
), 1, 0) AS DESCENDANTS
FROM
SEARCH_TREE
INNER JOIN DESIGNATIONS ON DES_ID = STR_DES_ID
INNER JOIN DES_TEXTS ON TEX_ID = DES_TEX_ID
WHERE
STR_ID_PARENT <=> @STR_ID AND
DES_LNG_ID = @LNG_ID AND
EXISTS
(
SELECT
*
FROM
LINK_GA_STR
INNER JOIN LINK_LA_TYP ON LAT_TYP_ID = @TYP_ID AND
LAT_GA_ID = LGS_GA_ID
INNER JOIN LINK_ART ON LA_ID = LAT_LA_ID
WHERE
LGS_STR_ID = STR_ID
LIMIT
1
)
;


Вот этот запрос вытягивает чилдренов по id родителя и проверяет, если ли у этих чилдренов подкатегории(1 или 0).
Я написал функцию, которая с помощью рекурсии строит это дерево, но загвоздка в том, что функция вызывает сама себя, и каждый раз она посылает запрос, а если дерево ветвистое, то получается сотня запросов и соответственно дерево строится около минуты. Как вообще можно оптимизировать этот процесс, может есть другой принцип построения?
<?
function
get_tree($root,$lang,$id,$connect){
$sql = "SET @TYP_ID =".$id;
$result = mysql_query($sql,$connect);
$sql = "SET @LNG_ID = $lang;"; /* 1 - Ќемецкий €зык; 16 - –усский €зык 4 - english */
$result = mysql_query($sql,$connect);
$sql = "SET @STR_ID = $root";
$result = mysql_query($sql,$connect);
$sql = "SELECT
STR_ID,
TEX_TEXT AS STR_DES_TEXT,
IF(
EXISTS(
SELECT
*
FROM
SEARCH_TREE AS SEARCH_TREE2
WHERE
SEARCH_TREE2.STR_ID_PARENT <=> SEARCH_TREE.STR_ID
LIMIT
1
), 1, 0) AS DESCENDANTS
FROM
SEARCH_TREE
INNER JOIN DESIGNATIONS ON DES_ID = STR_DES_ID
INNER JOIN DES_TEXTS ON TEX_ID = DES_TEX_ID
WHERE
STR_ID_PARENT <=> @STR_ID AND
DES_LNG_ID = @LNG_ID AND
EXISTS (
SELECT
*
FROM
LINK_GA_STR
INNER JOIN LINK_LA_TYP ON LAT_TYP_ID = @TYP_ID AND
LAT_GA_ID = LGS_GA_ID
INNER JOIN LINK_ART ON LA_ID = LAT_LA_ID
WHERE
LGS_STR_ID = STR_ID
LIMIT
1
)
;"
;

//$sql = "SELECT distinct DES_LNG_ID from DESIGNATIONS";
$result = mysql_query($sql,$connect);

if (!$result) {
die('Invalid query: ' . mysql_error());
}
//$row = mysql_fetch_assoc ( $query );
$ajaxRes = array();
while ( $row = mysql_fetch_assoc ( $result ) ) {
$ajaxRes[] = $row;

}

?>
<?
foreach($ajaxRes as $res):?>
<?
if($res['DESCENDANTS'] == 1) : ?>
<li><a href="#"> <? echo $res['STR_DES_TEXT'];?> </a><ul>
<? echo get_tree($res['STR_ID'],$lang,$id,$connect);?>
<?
endif?>
<?
if($res['DESCENDANTS'] == 0) : ?>
<li><a href="javascript:void(0)" OnClick="SendData(<? echo $res['STR_ID']; ?>,6,'<?echo $res['STR_DES_TEXT'];?>')"> <? echo $res['STR_DES_TEXT'];?> </a></li>
<? endif ?>
<?
endforeach ?>
</ul></li>


<?}?>

Это функция. Вызывать так:
<? get_tree(10001,16,3822,$connect); ?>

По востребованию кину все данные для коннекта



Спустя 6 минут, 56 секунд (26.11.2011 - 09:42) Michael написал(а):
Посмотри - может тут что найдешь. Вообще и под mysql эта тема была на форуме и glock18 писал код в своем ответе, вот только я найти не могу ту тему. Отвечал он на вопрос вроде Семёна.

Спустя 18 минут, 25 секунд (26.11.2011 - 10:00) Эдик написал(а):
Ну тут по PostgreSQL, желательно бы по mysql....Ладно, сейчас поищу

Спустя 1 час, 22 минуты, 22 секунды (26.11.2011 - 11:23) Michael написал(а):
вот эта тема

Спустя 2 часа, 50 минут, 20 секунд (26.11.2011 - 14:13) caballero написал(а):
выгребаешь все в массив и бегаешь по нему -все равно быстрее чев лазить в БД.
А если по уму то надо организовавать дополнительные поля в таблицес указание уровня в иерарххии и все такое

Спустя 1 час, 46 минут, 22 секунды (26.11.2011 - 16:00) Эдик написал(а):
Так а как мне выгребсти весь массив? Все одно нужно каждый раз свой запрос посылать. А вот если бы одним запросом все....

Спустя 4 минуты, 30 секунд (26.11.2011 - 16:04) Семён написал(а):
Закешированные запросы в рекурсии совсем не страшны.

Спустя 15 минут, 43 секунды (26.11.2011 - 16:20) caballero написал(а):
Цитата (Эдик @ 26.11.2011 - 13:00)
Так а как мне выгребсти весь массив? Все одно нужно каждый раз свой запрос посылать. А вот если бы одним запросом все....

что значит как?
select * from SEARCH_TREE

Спустя 2 минуты, 38 секунд (26.11.2011 - 16:22) vital написал(а):
Велосипеды не писать, велосипеды не изобратать. Nested Sets

Спустя 6 минут, 1 секунда (26.11.2011 - 16:28) Эдик написал(а):
Ну тут таблица мне чисто предоставляется, поэтому создать я ничего не могу, остается довольствоваться тем, что есть

Спустя 7 минут, 40 секунд (26.11.2011 - 16:36) Эдик написал(а):
Семён? в смысле закешированные? Там же на каждый запрос результат то будет разный, поэтому они не могут кешироваться


Спустя 7 минут, 57 секунд (26.11.2011 - 16:44) Эдик написал(а):
caballero, а и кстати весь массив нереально вытянуть, потому что там твое дерево зависит от id предыдущего шага, в дереве понамешано для всех id, которые мне не надо вообще. такая вот проблема...

Спустя 2 часа, 30 минут, 17 секунд (26.11.2011 - 19:14) caballero написал(а):
и что что понамешано
оббегаешь циклом и берешь нужные
тупо конечно но лучше и быстрее сотни запросов в базу
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.