Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Объеденить 2 и 3 запроса в 1
 
 автор: TetRiska   (11.03.2011 в 15:04)   письмо автору
 
 

Всем привет. Прошу помощи подправить мои запросы. время исполнения первого 73мс, второго 93мс...
SELECT
   p.`em_partner_file`,
   p.`em_partner_title`
FROM
   `em_partner_block` p
JOIN `em_category` c
ON (p.`em_category_id`=c.`em_category_parent_id`)
WHERE
   p.em_category_id = (
                      SELECT
                 em_category_parent_id
              FROM
             `em_category`
              WHERE
              em_category_id = 40
                      ) AND 
   p.`em_partner_access`='y' AND
   p.`em_partner_deleted`='n'
GROUP BY
   p.`em_partner_id`
ORDER BY
   p.`em_partner_sort` ASC

SELECT
   p.`em_partner_file`,
   p.`em_partner_title`
FROM
   `em_partner_block` p
JOIN `em_category` c
ON (p.`em_category_id`=c.`em_category_parent_id`)
WHERE
   p.`em_category_id` = (
                    SELECT
            `em_category_parent_id`
            FROM
            `em_category`
            WHERE
            `em_category_id` = (
                                        SELECT
                        `em_category_parent_id`
                    FROM
                        `em_category`
                    WHERE
                        `em_category_id` = 303
                                           )
                       ) AND 
   p.`em_partner_access`='y' AND
   p.`em_partner_deleted`='n'
GROUP BY
   p.`em_partner_id`
ORDER BY
   p.`em_partner_sort` ASC

Получается такая картина... На сайте тройная вложенность страниц...На первой мы пишем простой запрос для выборки данных из таблицы категории. На второй странице мы определяем подкатегорию после чего мы это значение вставляем в основной запрос. На третей странице у нас похожая ситуация. Мы определяем подподкатегорию, вставляем в запрос подкатегории, после чего вставляем в основной запрос. Как упростить кто подскажет? Спасибо.

  Ответить  
 
 автор: cheops   (11.03.2011 в 15:28)   письмо автору
 
   для: TetRiska   (11.03.2011 в 15:04)
 

1) А проблема в чем заключается, в том что запросы медленно выполняются?
2) Если не сложно прикрепите дампы таблиц (без данных), которые получаются при помощи запроса SHOW CREATE TABLE (на ключи хочется посмотреть). И сообщите объем таблиц (в Мб).

PS Вложенные запросы (в вашем случае точно) можно преобразовать в объединение таблиц, что позволит ускорить выборку.

  Ответить  
 
 автор: cheops   (11.03.2011 в 15:34)   письмо автору
 
   для: cheops   (11.03.2011 в 15:28)
 

Для начала первый запрос следует преобразовать как-то так
SELECT 
   p.`em_partner_file`, 
   p.`em_partner_title` 
FROM 
   `em_partner_block` p 
JOIN `em_category` c 
ON (p.`em_category_id`=c.`em_category_parent_id`)
JOIN `em_category` cp
ON (p.em_category_id = cp.em_category_parent_id AND cp.em_category_id = 40)
WHERE
   p.`em_partner_access`='y' AND 
   p.`em_partner_deleted`='n' 
GROUP BY 
   p.`em_partner_id` 
ORDER BY 
   p.`em_partner_sort` ASC

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 16:23)   письмо автору
 
   для: cheops   (11.03.2011 в 15:34)
 

этот запрос 94мс выполняется, мой что первый 73мс

  Ответить  
 
 автор: cheops   (11.03.2011 в 16:53)   письмо автору
 
   для: TetRiska   (11.03.2011 в 16:23)
 

Добавьте индекс на столбец em_category_id таблицы em_partner_block. Как изменилось время?

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 17:37)   письмо автору
 
   для: cheops   (11.03.2011 в 16:53)
 

PRIMARY KEY  (`em_partner_id`)
  KEY `em_category_id` (`em_category_id`),


так? это в таблице em_partner_block

  Ответить  
 
 автор: cheops   (11.03.2011 в 17:42)   письмо автору
 
   для: TetRiska   (11.03.2011 в 17:37)
 

Да, только запятая после PRIMARY KEY, а не после KEY.

В уже в существующую таблицу можно добавить его так
ALTER TABLE `em_partner_block` ADD INDEX ( `em_category_id` )

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 17:47)   письмо автору
 
   для: cheops   (11.03.2011 в 17:42)
 

да никак, 94мс так и осталось

  Ответить  
 
 автор: cheops   (11.03.2011 в 18:00)   письмо автору
 
   для: TetRiska   (11.03.2011 в 17:47)
 

А теперь попробуйте вот такой запрос - у него время уменьшается?
SELECT 
   p.`em_partner_file`, 
   p.`em_partner_title` 
FROM 
   (SELECT * FROM `em_partner_block`
    WHERE em_partner_access='y' AND 
           em_partner_deleted='n') AS p 
JOIN `em_category` c 
ON (p.`em_category_id`=c.`em_category_parent_id`) 
WHERE 
   p.em_category_id = ( 
                      SELECT 
                 em_category_parent_id 
              FROM 
             `em_category` 
              WHERE 
              em_category_id = 40 
                      )
GROUP BY 
   p.`em_partner_id` 
ORDER BY 
   p.`em_partner_sort` ASC

PS Вообще бы, конечно, полный бы дамп - с ним повозиться, так как EXPLAIN у меня жалуется на отсутствие данных, не понятно какой индекс используется, а какой нет.

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 18:37)   письмо автору
 
   для: cheops   (11.03.2011 в 18:00)
 

Время аналогичное. А нельзя ли сделать полостью на джоинах? А то вложенные запросы как говорилось замедляют исполнение. Насчет дампа - с данными что ли?

  Ответить  
 
 автор: cheops   (11.03.2011 в 18:40)   письмо автору
 
   для: TetRiska   (11.03.2011 в 18:37)
 

Можно (смотрите ниже), но дело не в JOIN-ах и вложенных запросах, а в том, чтобы подцепить индексы, а они судя по всему почему-то не подцепляются. Поставьте перед SELECT-запросом ключевое слово EXPLAIN - посмотрите, что он сообщает.
SELECT  
   p.`em_partner_file`,  
   p.`em_partner_title`  
FROM  
    (SELECT * FROM `em_partner_block` 
    WHERE em_partner_access='y' AND  
           em_partner_deleted='n') AS p  
JOIN `em_category` c  
ON (p.`em_category_id`=c.`em_category_parent_id`) 
JOIN `em_category` cp 
ON (p.em_category_id = cp.em_category_parent_id AND cp.em_category_id = 40) 
GROUP BY  
   p.`em_partner_id`  
ORDER BY  
   p.`em_partner_sort` ASC

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 19:02)   письмо автору
97.9 Кб
 
   для: cheops   (11.03.2011 в 18:40)
 

EXPLAIN поставил в самом начале запроса перед селект...см. приложение

  Ответить  
 
 автор: cheops   (11.03.2011 в 19:17)   письмо автору
 
   для: TetRiska   (11.03.2011 в 19:02)
 

Скорость не изменилась? По прежнему 94мс? Кстати, имеются в виду микро или милисекунды (может уже ограничение в подсчете времени и точно у этих значений скорость уже не измерить)?

PS Ключи используется, по сравнению с первым запросом мы перевели полностью его на объединения, даже избавились от WHERE-конструкции. Индексы тоже вроде все в наличии.

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 19:29)   письмо автору
 
   для: cheops   (11.03.2011 в 19:17)
 

уже реже чем 94мс стало выполнятся...колеблется от 63мс до 94мс

  Ответить  
 
 автор: cheops   (11.03.2011 в 19:39)   письмо автору
 
   для: TetRiska   (11.03.2011 в 19:29)
 

Если колеблется, значит уже не от скрипта скорость зависит, а от нагрузки машины - загоняйте запросы в циклы, чтобы время поточнее оценивать.

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 20:08)   письмо автору
 
   для: cheops   (11.03.2011 в 19:39)
 

ок, спасибо, буду тестировать

  Ответить  
 
 автор: cheops   (11.03.2011 в 15:37)   письмо автору
 
   для: cheops   (11.03.2011 в 15:28)
 

Второй запрос, для начала давайте, для начала, преобразуем так (сообщите скорость его выполнения, нужно ли его дальше преобразовывать)
SELECT 
   p.`em_partner_file`, 
   p.`em_partner_title` 
FROM 
   `em_partner_block` p 
JOIN `em_category` c 
ON (p.`em_category_id`=c.`em_category_parent_id`) 
WHERE 
   p.`em_category_id` = ( 
                    SELECT 
            `ic.em_category_parent_id` 
            FROM 
            `em_category` ic
            JOIN `em_category` ip
            ON (ic.em_category_id = ip.em_category_parent_id AND
                ip.em_category_id = 300)) AND  
   p.`em_partner_access`='y' AND 
   p.`em_partner_deleted`='n' 
GROUP BY 
   p.`em_partner_id` 
ORDER BY 
   p.`em_partner_sort` ASC

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 16:25)   письмо автору
 
   для: cheops   (11.03.2011 в 15:37)
 

этот вообще ругнулся Unknown column 'ic.em_category_parent_id' in 'field list', не пойму где ошибка

  Ответить  
 
 автор: cheops   (11.03.2011 в 16:52)   письмо автору
 
   для: TetRiska   (11.03.2011 в 16:25)
 

Сейчас попробую в минимально формате базу данных воспроизвести и повозиться с запросами непосредственно, а не умозрительно.

  Ответить  
 
 автор: cheops   (11.03.2011 в 17:44)   письмо автору
 
   для: TetRiska   (11.03.2011 в 16:25)
 

Исправьте запрос следующим образом
SELECT  
   p.`em_partner_file`,  
   p.`em_partner_title`  
FROM  
   `em_partner_block` p  
JOIN `em_category` c  
ON (p.`em_category_id`=c.`em_category_parent_id`)  
WHERE  
   p.`em_category_id` = (  
                    SELECT  
            ic.em_category_parent_id
            FROM  
            `em_category` ic 
            JOIN `em_category` ip 
            ON (ic.em_category_id = ip.em_category_parent_id AND 
                ip.em_category_id = 300)) AND   
   p.`em_partner_access`='y' AND  
   p.`em_partner_deleted`='n'  
GROUP BY  
   p.`em_partner_id`  
ORDER BY  
   p.`em_partner_sort` ASC

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 16:22)   письмо автору
 
   для: cheops   (11.03.2011 в 15:28)
 

1 - вложенные запросы дольше выполняются как пишет народ...поэтому хочется оптимизации
2
CREATE TABLE `em_category` (
  `em_category_id` int(10) unsigned NOT NULL auto_increment,
  `em_category_parent` int(10) unsigned NOT NULL default '0',
  `em_category_module` enum('produce','service') collate utf8_unicode_ci NOT NULL default 'produce',
  `em_category_idn` varchar(20) character set cp1251 NOT NULL default '',
  `em_element_id` tinyint(3) unsigned NOT NULL default '0',
  `em_language_id` tinyint(3) unsigned NOT NULL default '1',
  `em_category_parent_id` int(10) unsigned NOT NULL default '0',
  `em_category_level` tinyint(3) unsigned NOT NULL default '1',
  `em_category_name` varchar(64) collate utf8_unicode_ci NOT NULL default '',
  `em_category_image` varchar(255) character set cp1251 NOT NULL default '',
  `em_category_weight` smallint(5) unsigned NOT NULL default '100',
  `em_category_count_produce` int(10) unsigned NOT NULL default '0',
  `em_category_count_service` int(10) unsigned NOT NULL default '0',
  `em_category_count_company` int(10) unsigned NOT NULL default '0',
  `em_category_count_event` int(10) unsigned NOT NULL default '0',
  `em_category_access` enum('y','n') collate utf8_unicode_ci NOT NULL default 'y',
  `em_category_deleted` enum('y','n') collate utf8_unicode_ci NOT NULL default 'n',
  PRIMARY KEY  (`em_category_id`),
  KEY `em_category_parent_id` (`em_category_parent_id`),
  KEY `em_category_name` (`em_category_name`),
  KEY `em_category_weight` (`em_category_weight`),
  KEY `em_category_access` (`em_category_access`,`em_category_deleted`),
  KEY `em_element_id` (`em_element_id`),
  KEY `em_category_parent` (`em_category_parent`),
  KEY `em_category_level` (`em_category_level`),
  KEY `em_language_id` (`em_language_id`)
) ENGINE=MyISAM AUTO_INCREMENT=6128 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `em_partner_block` (
  `em_partner_id` int(3) unsigned NOT NULL auto_increment,
  `em_category_id` int(5) unsigned NOT NULL default '0',
  `em_partner_title` varchar(50) collate utf8_unicode_ci NOT NULL default '',
  `em_partner_file` varchar(50) collate utf8_unicode_ci NOT NULL default '',
  `em_partner_sort` int(3) unsigned NOT NULL default '0',
  `em_partner_access` enum('y','n') collate utf8_unicode_ci NOT NULL default 'y',
  `em_partner_deleted` enum('y','n') collate utf8_unicode_ci NOT NULL default 'n',
  PRIMARY KEY  (`em_partner_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

по объему не скажу, нужно писать скрипт, что не очень хочется...из дампа видно количество записей

  Ответить  
 
 автор: cheops   (11.03.2011 в 16:49)   письмо автору
 
   для: TetRiska   (11.03.2011 в 16:22)
 

>по объему не скажу, нужно писать скрипт, что не очень хочется...из дампа видно количество
>записей
Посмотрите в SHOW STATUS или прямо в phpMyAdmin - это мета-информация, она в заголовках таблиц хранится.

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 16:56)   письмо автору
 
   для: cheops   (11.03.2011 в 16:49)
 

у меня нет доступа к пхп май админу....пользуюсь скуль менеджером...там свойства таблицы есть, но не показывает ее объем

  Ответить  
 
 автор: cheops   (11.03.2011 в 17:05)   письмо автору
 
   для: TetRiska   (11.03.2011 в 16:56)
 

Выполните запросы
SHOW TABLE STATUS LIKE 'em_category' \G
SHOW TABLE STATUS LIKE 'em_partner_block' \G
Какие значения в поле Data_length?

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 17:42)   письмо автору
 
   для: cheops   (11.03.2011 в 17:05)
 

em_category - 349088
em_partner_block - 180

  Ответить  
 
 автор: cheops   (11.03.2011 в 17:47)   письмо автору
 
   для: TetRiska   (11.03.2011 в 17:42)
 

Ага, в общем не очень большие таблицы и порядок таблиц в запросах у вас верный. Тестируете эти запросы на сервере или на локальной машине?

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 17:48)   письмо автору
 
   для: cheops   (11.03.2011 в 17:47)
 

на сервере удаленно

  Ответить  
 
 автор: cheops   (11.03.2011 в 15:39)   письмо автору
 
   для: TetRiska   (11.03.2011 в 15:04)
 

Кстати, а что за столбец p.`em_partner_id` в GROUP BY? Он какую функцию несет?

  Ответить  
 
 автор: TetRiska   (11.03.2011 в 16:22)   письмо автору
 
   для: cheops   (11.03.2011 в 15:39)
 

группирует, без него выводит дубли...странно в общем-то

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования