SQLinfo.ru - Все о MySQL

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

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

Вы не зашли.

#1 29.08.2011 14:02:48

sergej-123
Участник
Зарегистрирован: 29.08.2011
Сообщений: 6

MySQL меняет порядок условий в WHERE

Добрый день,

Столкнулся с проблемой, что mysql меняет порядок условий в WHERE.

Есть база:


CREATE TABLE IF NOT EXISTS `con` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `cid` int(11) NOT NULL,
  `cdate` date NOT NULL,
  `type` smallint(6) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_CID` (`cid`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

INSERT INTO `con` (`id`, `cid`, `cdate`, `type`) VALUES
(2, 2, '2011-08-11', 1),
(3, 3, '2011-06-01', 2),
(4, 4, '2011-06-15', 2);

CREATE TABLE IF NOT EXISTS `hist` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_con` int(11) NOT NULL,
  `update` date NOT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_CON` (`id_con`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

INSERT INTO `hist` (`id`, `id_con`, `update`) VALUES
(1, 2, '2011-08-29'),
(2, 2, '2011-08-01'),
(3, 2, '2011-07-20'),
(4, 3, '2011-06-08'),
(5, 4, '2011-06-23');
 


Выполняем запрос:

explain SELECT
    c.cdate,
    c.type,
    h.id_con,
    max(h.update)    AS `update`,
    date_ymd         AS max_update,
    n                AS `month`
FROM
    con c,
    hist h,
    (
        SELECT '2011-08-25' AS date_ymd, 0 AS n
        UNION SELECT '2011-07-31', 1
        UNION SELECT '2011-06-30', 2
    ) AS `month`
WHERE
    c.cid = 2 AND
    h.id_con = c.id AND
    `update`<= date_ymd
GROUP BY
    id_con, date_ymd;
 



Видим следующее
http://img855.imageshack.us/img855/8274/explain.gif

Uploaded with ImageShack.us

Т.е. всё по индексам проходит, всё ОК. Выполняем запрос и смотрим как mysql его преобразовывает

explain extended SELECT
    c.cdate,
    c.type,
    h.id_con,
    max(h.update)    AS `update`,
    date_ymd         AS max_update,
    n                AS `month`
FROM
    con c,
    hist h,
    (
        SELECT '2011-08-25' AS date_ymd, 0 AS n
        UNION SELECT '2011-07-31', 1
        UNION SELECT '2011-06-30', 2
    ) AS `month`
WHERE
    c.cid = 2 AND
    h.id_con = c.id AND
    `update`<= date_ymd
GROUP BY
    id_con, date_ymd;
 



MySQL отдает, и собственно пытается выполнить, вот такой запрос:
select
    `test`.`c`.`cdate` AS `cdate`,
    `test`.`c`.`type` AS `type`,
    `test`.`h`.`id_con` AS `id_con`,
    max(`test`.`h`.`update`) AS `update`,
    `month`.`date_ymd` AS `max_update`,
    `month`.`n` AS `month`
from
    `test`.`con` `c`
join
    `test`.`hist` `h`
join (
    select '2011-08-25' AS `date_ymd`,0 AS `n`
    union select '2011-07-31' AS `2011-07-31`,1 AS `1`
    union select '2011-06-30' AS `2011-06-30`,2 AS `2`
) `month`
where (
    (`test`.`c`.`id` = `test`.`h`.`id_con`) and
    (`test`.`c`.`cid` = 2) and
    (`test`.`h`.`update` <= `month`.`date_ymd`)
)
group by
`test`.`h`.`id_con`,`month`.`date_ymd`



Как видим MySQL поменял очередность условий в WHERE (1 и 2 условие), что не очень хорошо сказывается на больших объемах данных.
Пробовал в запросе в WHERE брать условия в скобки () чтобы указать очередность, но толку нет, всё равно MySQL именно так преобразовывает. Что делать?

Неактивен

 

#2 29.08.2011 15:35:55

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

Re: MySQL меняет порядок условий в WHERE

sergej-123 написал:

MySQL отдает, и собственно пытается выполнить, вот такой запрос:

Это где вы смотрите?

sergej-123 написал:

Как видим MySQL поменял очередность условий в WHERE (1 и 2 условие), что не очень хорошо сказывается на больших объемах данных.
Пробовал в запросе в WHERE брать условия в скобки () чтобы указать очередность, но толку нет, всё равно MySQL именно так преобразовывает. Что делать?

"h.id_con = c.id" - это не условие в части where, а способ связывания таблиц, т.е. относится к части join, поэтому и выполняется всегда до where.

Поместите "c.cid = 2" в условие связывания таблиц или честно напишите подзапрос.

Неактивен

 

#3 29.08.2011 15:41:11

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: MySQL меняет порядок условий в WHERE

Как видим MySQL поменял очередность условий в WHERE (1 и 2 условие), что не очень хорошо сказывается на больших объемах данных.

С чего вы это взяли ?
Если есть аргументы, то сылку на источники пожалуйста.

Отредактированно evgeny (29.08.2011 15:42:41)

Неактивен

 

#4 29.08.2011 15:58:01

sergej-123
Участник
Зарегистрирован: 29.08.2011
Сообщений: 6

Re: MySQL меняет порядок условий в WHERE

vasya написал:

sergej-123 написал:

MySQL отдает, и собственно пытается выполнить, вот такой запрос:

Это где вы смотрите?

http://img822.imageshack.us/img822/842/explain2.gif
Uploaded with ImageShack.us

vasya написал:

sergej-123 написал:

Как видим MySQL поменял очередность условий в WHERE (1 и 2 условие), что не очень хорошо сказывается на больших объемах данных.
Пробовал в запросе в WHERE брать условия в скобки () чтобы указать очередность, но толку нет, всё равно MySQL именно так преобразовывает. Что делать?

"h.id_con = c.id" - это не условие в части where, а способ связывания таблиц, т.е. относится к части join, поэтому и выполняется всегда до where.

Поместите "c.cid = 2" в условие связывания таблиц или честно напишите подзапрос.

не понял как "c.cid = 2" добавить

Неактивен

 

#5 29.08.2011 16:05:23

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

Re: MySQL меняет порядок условий в WHERE

FROM    con c join    hist h on (c.cid = 2 AND    h.id_con = c.id)

Неактивен

 

#6 29.08.2011 16:32:50

sergej-123
Участник
Зарегистрирован: 29.08.2011
Сообщений: 6

Re: MySQL меняет порядок условий в WHERE

vasya написал:

FROM    con c join    hist h on (c.cid = 2 AND    h.id_con = c.id)

Не помогло
http://img402.imageshack.us/img402/6730/explain3.gif[/url]

Неактивен

 

#7 29.08.2011 17:41:49

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: MySQL меняет порядок условий в WHERE

очередность условий в WHERE (1 и 2 условие), что не очень хорошо сказывается на больших объемах данных.

vasya Можешь это прокомментировать ? Направить на материал ? Никогда не слышал что порядок условий может играть какую то роль.

Неактивен

 

#8 29.08.2011 17:48:22

sergej-123
Участник
Зарегистрирован: 29.08.2011
Сообщений: 6

Re: MySQL меняет порядок условий в WHERE

evgeny написал:

очередность условий в WHERE (1 и 2 условие), что не очень хорошо сказывается на больших объемах данных.

vasya Можешь это прокомментировать ? Направить на материал ? Никогда не слышал что порядок условий может играть какую то роль.

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

Неактивен

 

#9 29.08.2011 19:15:07

evgeny
Гуру
Зарегистрирован: 04.05.2009
Сообщений: 335

Re: MySQL меняет порядок условий в WHERE

Дайте какой то аргумент, либо сылку на материал. Так же был бы рад услышать мнение модераторов

Неактивен

 

#10 29.08.2011 23:19:56

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

Re: MySQL меняет порядок условий в WHERE

evgeny написал:

очередность условий в WHERE (1 и 2 условие), что не очень хорошо сказывается на больших объемах данных.

vasya Можешь это прокомментировать ? Направить на материал ? Никогда не слышал что порядок условий может играть какую то роль.

Тоже никогда о таком не слышал smile

Upd: Пардон, что-то я чушь написал прошлый раз. Вы совершенно правы.

Неактивен

 

#11 30.08.2011 08:37:47

sergej-123
Участник
Зарегистрирован: 29.08.2011
Сообщений: 6

Re: MySQL меняет порядок условий в WHERE

Эммммм.... немного не понял, всё-таки есть проблема или же я чего-то не понимаю?

Неактивен

 

#12 31.08.2011 10:00:18

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: MySQL меняет порядок условий в WHERE

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

Но проблемы я в этом не вижу, т.к. по словам автора изначального сообщения
«т.е. всё по индексам проходит, всё ОК» smile Запрос выполняется так, как написано
в EXPLAIN, и ничто не может ему помешать.

Неактивен

 

#13 01.09.2011 12:08:38

sergej-123
Участник
Зарегистрирован: 29.08.2011
Сообщений: 6

Re: MySQL меняет порядок условий в WHERE

paulus написал:

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

Но проблемы я в этом не вижу, т.к. по словам автора изначального сообщения
«т.е. всё по индексам проходит, всё ОК» smile Запрос выполняется так, как написано
в EXPLAIN, и ничто не может ему помешать.

Ладно, перефразирую вопрос, в поле rows в explain отдается значение около 10млн. при объединении двух таблиц (h.id_con = c.id), т.е. MySQL надо проанализировать 10млн строк для выполнения запроса, а только после этого выбираются записи, которые удовлетворяют условию "c.cid = 2".

Если я правильно понимаю, то если бы первым обработалось условие "c.cid = 2", выбрав при этом 20 строк, то объединять 2 таблицы было бы сделано с меньшими затратами. Я прав?

Неактивен

 

#14 01.09.2011 13:20:27

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

Re: MySQL меняет порядок условий в WHERE

Ипсользуйте

SELECT STRAIGHT_JOIN ...

в этом случае порядок объединения таблиц изменяться не будет (объединение будет выполнено в том порядке, в котором таблицы перечислены)

Неактивен

 

#15 01.09.2011 23:37:47

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: MySQL меняет порядок условий в WHERE

Но если Вы перечислите таблицы плохо, то будет только хуже (и MySQL очень редко
ошибается, когда выбирает порядок следования таблиц). Если MySQL выбирает другой
(по сравнению с тем, который Вы предполагаете) порядок объединения таблиц — это,
скорее всего, признак того, что не хватает какого-то индекса (в Вашем примере — над
теми 20 строками. И выбирать такую таблицу первой оказывается менее выгодным).

Неактивен

 

Board footer

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