За последние 24 часа нас посетили 52534 программиста и 1797 роботов. Сейчас ищут 814 программистов ...

Оптимизироватпь количество запросов

Тема в разделе "MySQL", создана пользователем Good][Man, 11 сен 2009.

  1. Good][Man

    Good][Man Активный пользователь

    С нами с:
    23 авг 2009
    Сообщения:
    35
    Симпатии:
    0
    Адрес:
    eWorld
    Здравствуйте всем.В общем помогите пожалуйста оптимизировать количество запросов к БД.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:
    1. <?php
    2.       public function sql_query($query_str) {
    3.           ( $this->result = mysql_query($query_str,$this->link) ) || ($this->translate_error());
    4.           //print query if debug
    5.            if($this->debuglevel >= 2) print_r('<br>'.$query_str.'<p>');
    6.  
    7.            return $this->result;
    8.       }
    9.      
    10.       public function fetch($mode = MYSQL_ASSOC) {
    11.           return mysql_fetch_array($this->result,$mode);
    12.       }
    13.      
    14.       public function fetched_array($mode = MYSQL_ASSOC) {
    15.          
    16.           $arr_fetched = array();
    17.          
    18.           while( $result = mysql_fetch_array($this->result,$mode) ):
    19.               $arr_fetched[] = $result;
    20.           endwhile;
    21.          
    22.           if( $this->num_rows() >0 )
    23.             return $arr_fetched;
    24.           else
    25.             return false;
    26.       }
    27. ?>
    28.      


    file : favourite.php
    PHP:
    1. <?php
    2.  
    3. require_once("include/default.inc.php");
    4.  
    5. $id = 30;
    6.  
    7.    
    8. $sql = <<<SQL
    9. SELECT `id_restaurant`
    10. FROM `favourites`
    11. WHERE `id_user` =$id
    12. ORDER BY RAND() LIMIT 5
    13. SQL;
    14.  
    15. if($dbSQL->sql_query($sql)):
    16.     $data = $dbSQL->fetched_array();
    17.     foreach ($data as $r_info):      
    18.         $id_restaurant = array_shift($r_info);
    19.         $sql = sprintf("SELECT `name` FROM `restaurant` WHERE `id` = %s",$id_restaurant);
    20.         $dbSQL->sql_query($sql);
    21.         $r_name = array_shift($dbSQL->fetch());            
    22.         $sql = sprintf("SELECT `id`,`name` FROM `complex` WHERE `date` = CURDATE( ) AND `id_restaurant` = %s",$id_restaurant);
    23.         if($dbSQL->sql_query($sql)):
    24.             $c_data = $dbSQL->fetched_array(MYSQL_BOTH);
    25.             while (list ($_id,$_name) = @current($c_data)):
    26.                 $sql = sprintf("SELECT `name` FROM `dish` WHERE `id_complex` =%s",$_id);
    27.                 if($dbSQL->sql_query($sql)):
    28.                     while($dish_name = @array_shift($dbSQL->fetch())):                                                    
    29.                     endwhile;
    30.                  endif;
    31.                  next($c_data);
    32.             endwhile;
    33.         endif;
    34.     endforeach;
    35. else:
    36.     $html_block .="пусто в избранном";
    37. endif;                  
    38.  
    39. ?>
     
  2. Good][Man

    Good][Man Активный пользователь

    С нами с:
    23 авг 2009
    Сообщения:
    35
    Симпатии:
    0
    Адрес:
    eWorld
    можете составить запрос с помощью INNER что бы забрать все данные из таблиц.
     
  3. lexa

    lexa Активный пользователь

    С нами с:
    22 июл 2007
    Сообщения:
    1.746
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    [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. Логика моя такая: отсеиваем по дате (быстро), затем ловим связи ресторанов и обедов, потом снова ловим связи, но уже обедов и блюд.

    Могу ошибаться и в запросе, и в логике. Можно отловить сначала все связи, потом уже и фильтровать по дате.