Здравствуйте всем.В общем помогите пожалуйста оптимизировать количество запросов к БД.SQL я знаю слабо поэтому прошу помощи. Код приведенный ниже- это избранное пользователя, в избранном хранятся рестораны которые он добавил, под ресторанами выводятся комплексы на сегодня и под комплексами выводятся ихние содержание aka блюда. Какие запросы направляются к БД: -запрос на извлечение ресторанов из БД находящиеся в избранном -запрос на извлечение имя текущего ресторана из БД -запрос на извлечение комплексов текущего ресторана на сегоднешний день. -запрос на извлечение блюд текущего комплекса. максимальное количество запросов к Базе Данных : 1+3*5 = 16 запросов если данные берутся по максимуму, то есть 5 ресторанов у каждого на сегодня в меню есть комплекс. И это только избранное пользователя 20 запросов а избранное выводится на главной стр. Там еще есть запросы в итоге получается слишком много.Поэтому прошу вас помочь с оптимизацией. Ниже будут приведены MySQL таблицы,PHP code. MySQL Table: [sql] -- -- Структура таблицы `favourites` -- CREATE TABLE `favourites` ( `id` smallint(4) unsigned NOT NULL auto_increment, `id_user` int(4) unsigned NOT NULL, `id_restaurant` int(4) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `id_user` (`id_user`,`id_restaurant`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -- Дамп данных таблицы `favourites` -- INSERT INTO `favourites` VALUES (1, 30, 1); INSERT INTO `favourites` VALUES (2, 30, 2); INSERT INTO `favourites` VALUES (3, 30, 3); INSERT INTO `favourites` VALUES (4, 30, 4); -- -- Структура таблицы `restaurant` -- CREATE TABLE `restaurant` ( `id` int(4) unsigned NOT NULL auto_increment, `city` tinyint(2) NOT NULL, `name` varchar(255) NOT NULL, `adress` varchar(255) default NULL, `tel` varchar(255) default NULL, `mail` varchar(255) default NULL, `site` varchar(255) default NULL, `info` text NOT NULL, `separate_order` tinyint(1) NOT NULL, `paid` tinyint(1) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- Дамп данных таблицы `restaurant` -- INSERT INTO `restaurant` VALUES (1, 1, 'Ресторан 1.1', NULL, NULL, NULL, NULL, '', 0, 0); INSERT INTO `restaurant` VALUES (2, 1, 'Ресторан 1.2', NULL, NULL, NULL, NULL, '', 0, 0); INSERT INTO `restaurant` VALUES (3, 1, 'Ресторан 1.3', NULL, NULL, NULL, NULL, '', 0, 0); INSERT INTO `restaurant` VALUES (4, 1, 'Ресторан 1.4', NULL, NULL, NULL, NULL, '', 0, 0); INSERT INTO `restaurant` VALUES (5, 1, 'Ресторан 1.5', NULL, NULL, NULL, NULL, '', 0, 0); INSERT INTO `restaurant` VALUES (6, 1, 'Ресторан 1.6', NULL, NULL, NULL, NULL, '', 0, 0); INSERT INTO `restaurant` VALUES (7, 1, 'Ресторан 1.7', NULL, NULL, NULL, NULL, '', 0, 0); INSERT INTO `restaurant` VALUES (8, 1, 'Ресторан 1.8', NULL, NULL, NULL, NULL, '', 0, 0); INSERT INTO `restaurant` VALUES (9, 1, 'Ресторан 1.9', NULL, NULL, NULL, NULL, '', 0, 0); -- -- Структура таблицы `complex` -- CREATE TABLE `complex` ( `id` int(4) unsigned NOT NULL auto_increment, `id_restaurant` int(4) unsigned NOT NULL, `name` varchar(255) NOT NULL, `date` date NOT NULL, `price` int(5) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `date` (`date`,`price`), KEY `id_restaurant` (`id_restaurant`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -- Дамп данных таблицы `complex` -- INSERT INTO `complex` VALUES (1, 1, 'free', '2009-09-10', 400); INSERT INTO `complex` VALUES (2, 1, 'test2', '2009-09-10', 4001); INSERT INTO `complex` VALUES (3, 1, 'rwer', '2009-09-10', 5551); -- -- Структура таблицы `dish` -- CREATE TABLE `dish` ( `id` int(4) unsigned NOT NULL auto_increment, `id_complex` int(4) unsigned NOT NULL, `name` varchar(255) NOT NULL, `size` smallint(4) unsigned NOT NULL, `price` int(4) unsigned NOT NULL, `favourite` tinyint(1) NOT NULL, PRIMARY KEY (`id`), KEY `id_complex` (`id_complex`,`favourite`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -- Дамп данных таблицы `dish` -- INSERT INTO `dish` VALUES (1, 1, 'Пюре', 50, 50, 0); INSERT INTO `dish` VALUES (2, 1, 'булочка', 150, 75, 0); [/sql] отдельные методы из mysql.class PHP: <?php public function sql_query($query_str) { ( $this->result = mysql_query($query_str,$this->link) ) || ($this->translate_error()); //print query if debug if($this->debuglevel >= 2) print_r('<br>'.$query_str.'<p>'); return $this->result; } public function fetch($mode = MYSQL_ASSOC) { return mysql_fetch_array($this->result,$mode); } public function fetched_array($mode = MYSQL_ASSOC) { $arr_fetched = array(); while( $result = mysql_fetch_array($this->result,$mode) ): $arr_fetched[] = $result; endwhile; if( $this->num_rows() >0 ) return $arr_fetched; else return false; } ?> file : favourite.php PHP: <?php require_once("include/default.inc.php"); $id = 30; $sql = <<<SQL SELECT `id_restaurant` FROM `favourites` WHERE `id_user` =$id ORDER BY RAND() LIMIT 5 SQL; if($dbSQL->sql_query($sql)): $data = $dbSQL->fetched_array(); foreach ($data as $r_info): $id_restaurant = array_shift($r_info); $sql = sprintf("SELECT `name` FROM `restaurant` WHERE `id` = %s",$id_restaurant); $dbSQL->sql_query($sql); $r_name = array_shift($dbSQL->fetch()); $sql = sprintf("SELECT `id`,`name` FROM `complex` WHERE `date` = CURDATE( ) AND `id_restaurant` = %s",$id_restaurant); if($dbSQL->sql_query($sql)): $c_data = $dbSQL->fetched_array(MYSQL_BOTH); while (list ($_id,$_name) = @current($c_data)): $sql = sprintf("SELECT `name` FROM `dish` WHERE `id_complex` =%s",$_id); if($dbSQL->sql_query($sql)): while($dish_name = @array_shift($dbSQL->fetch())): endwhile; endif; next($c_data); endwhile; endif; endforeach; else: $html_block .="пусто в избранном"; endif; ?>
[sql]SELECT `complex`.`id` as `c_id`, `complex`.`name` as `c_name`, `dish`.`name` as `d_name` FROM `restaurant`, `complex`, `dish` WHERE `complex`.`date` = CURDATE( ) AND `restaurant`.`id` = `id_restaurant` AND `id_complex` = `c_id`[/sql] Как-то так. P.S. Логика моя такая: отсеиваем по дате (быстро), затем ловим связи ресторанов и обедов, потом снова ловим связи, но уже обедов и блюд. Могу ошибаться и в запросе, и в логике. Можно отловить сначала все связи, потом уже и фильтровать по дате.