SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 13.03.2012 05:42:09

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

подзапросы зависимые и независимые

CREATE TABLE `t1` (
  `c1` int(11) DEFAULT NULL,
  `c11` int(11) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1

CREATE TABLE `t2` (
  `c2` int(11) DEFAULT NULL,
  `c22` int(11) NOT NULL DEFAULT '1',
  `c23` int(11) NOT NULL DEFAULT '1',
  KEY `c2` (`c2`),
  KEY `c22` (`c22`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

mysql> select * from t1;
+------+-----+
| c1   | c11 |
+------+-----+
|    1 |   1 |
|    2 |   1 |
|    3 |   1 |
|   16 |   1 |
|   17 |   1 |
|   18 |   1 |
|  111 |   1 |
+------+-----+

mysql> select * from t2;
+------+-----+-----+
| c2   | c22 | c23 |
+------+-----+-----+
|    2 |   1 |   1 |
|    4 |   1 |   1 |
|    5 |   1 |   1 |
|    6 |   1 |   1 |
|    7 |   1 |   1 |
|    8 |   1 |   1 |
|   11 |   1 |   1 |
|    2 |   1 |   1 |
+------+-----+-----+



Следующий подзапрос является зависимым:

mysql> explain extended select c1 from t1 where (c1,c11) in (select c2,c22 from
t2)\G
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: t1
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 7
     filtered: 100.00
        Extra: Using where
*************************** 2. row ***************************
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: t2
         type: ALL
possible_keys: c2,c22
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 8
     filtered: 75.00
        Extra: Using where
2 rows in set, 1 warning (0.09 sec)

mysql> show warnings;
+-------+------+----------------------------------------------------------------
| Level | Code | Message|
+-------+------+----------------------------------------------------------------
| Note  | 1003 | select `test`.`t1`.`c1` AS `c1` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`c1`,`test`.`t1`.`c11`),<exists>(select `test`.`t2`.`c2`,`test`.`t2`.`c22` from `test`.`t2` where ((<cache>(`test`.`t1`.`c1`) = `test`.`t2`.`c2`) and (<cache>(`test`.`t1`.`c11`) = `test`.`t2`.`c22`)))) |
+-------+------+----------------------------------------------------------------

1 row in set (0.00 sec)


Следующий подзапрос является независимым:

mysql> explain extended select c1 from t1 where (c1,c11) in (select c2,c22 from
t2 where c2>1 and c22<20)\G
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: t1
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 7
     filtered: 100.00
        Extra: Using where
*************************** 2. row ***************************
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: t2
         type: index_subquery
possible_keys: c2,c22
          key: c2
      key_len: 5
          ref: func
         rows: 4
     filtered: 100.00
        Extra: Using where
2 rows in set, 1 warning (0.00 sec)

mysql> show warnings;
+-------+------+-------------------------------------------------------------------------------------------------+
| Level | Code | Message                                 |
+-------+------+-------------------------------------------------------------------------------------------------+
| Note  | 1003 | select `test`.`t1`.`c1` AS `c1` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`c1`,`test`.`t1`.`c11`),<exists>(<index_lookup>(<cache>(`test`.`t1`.`c1`) in t2 on c2 where ((`test`.`t2`.`c2` > 1) and (`test`.`t2`.`c22` < 20) and (<cache>(`test`.`t1`.`c1`) = `test`.`t2`.`c2`) and (<cache>(`test`.`t1`.`c11`) = `test`.`t2`.`c22`))))) |
+-------+------+-------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)


Если сравнить планы отдельно подзапросов, то мы увидим расхождение в части possible_keys
mysql> explain select c2,c22 from t2  where c2>1 and c22<20\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t2
         type: ALL
possible_keys: c2,c22
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 8
        Extra: Using where
1 row in set (0.01 sec)

mysql> explain select c2,c22 from t2\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t2
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 8
        Extra:
1 row in set (0.00 sec)
 


P.S. что значит <index_lookup> в переписанном оптимизатором независимом подзапросе?

Неактивен

 

#2 13.03.2012 19:30:06

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: подзапросы зависимые и независимые

У тебя оба subquery отображаются как dependent. В чем тогда вопрос?

P.S. Наверное нужно смотреть исходный код MySQL, чтобы понять назначение ключевых слов в плане исполнения.

Неактивен

 

#3 13.03.2012 19:36:37

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: подзапросы зависимые и независимые

Проверял через профайлинг - один из них исполняется как независимый другой как зависимый.
Собственно это не вопрос, а иллюстрация к тому в каких случаях оптимизатор правильно выполняет независимый подзапрос в in и как на это можно повлиять с помощью индексов не переписывая запрос (это чтобы в письме простыню не писать).

Неактивен

 

#4 13.03.2012 20:23:08

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: подзапросы зависимые и независимые

rgbeast написал:

P.S. Наверное нужно смотреть исходный код MySQL, чтобы понять назначение ключевых слов в плане исполнения.

Само собой, но некоторые вещи можно понять из документации - http://forge.mysql.com/wiki/MySQL_Inter … formations
К тому же есть на форуме, те кто по долгу службы пилят исходники (это скорее надежда).

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson