powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Ручной порядок
30 сообщений из 30, показаны все 2 страниц
Ручной порядок
    #39077498
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
/* первый вариант */
select * from (select * from t where a = 1) x where b = 1;

/* второй вариант */
select * from (select * from t where b = 1) x where a = 1;


Вопрос: Существует ли разница между этими двумя запросами с точки зрения внутреннего выполнения?

Суть (откуда ноги у вопроса растут): если мы точно знаем, что одно условие существенно сужает подмножество и разумнее выполнить его первым, а уже последующими условиями ковыряться в сильно уменьшенном подмножестве, чем ковыряться сразу во всей базе, а затем сужать уже отковыренное подмножество...
...
Рейтинг: 0 / 0
Ручной порядок
    #39077518
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кэп говорит, что это зависит от наличия индексов на этих полях и от их кардиналити. Но может быть вы что-то ещё имели в виду?
...
Рейтинг: 0 / 0
Ручной порядок
    #39077556
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixесли мы точно знаем, что одно условие существенно сужает подмножество и разумнее выполнить его первым, а уже последующими условиями ковыряться в сильно уменьшенном подмножестве, чем ковыряться сразу во всей базе, а затем сужать уже отковыренное подмножество...
Ещё разумнее создать индекс по двум полям и выполнять
Код: sql
1.
select * from t where a = 1 and b = 1;
...
Рейтинг: 0 / 0
Ручной порядок
    #39077598
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix,

Очень хочется посоветовать книгу Льюис Джонатан "Oracle. Основы стоимостной оптимизации".
Там, конечно, больше половины к MySQL неприменимо, но все равно почитать стоит.
...
Рейтинг: 0 / 0
Ручной порядок
    #39077603
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaЕщё разумнее создать индекс по двум полям и выполнять
Код: sql
1.
select * from t where a = 1 and b = 1;

Зависит от соотношения селективности конкретных условий.
Бывает, что одно условие выбирает одну запись из миллиона, а второе каждую вторую. Тогда поле для второго условия скорее нет смысла включать в индекс.
...
Рейтинг: 0 / 0
Ручной порядок
    #39077614
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftБывает, что одно условие выбирает одну запись из миллиона, а второе каждую вторую. Тогда поле для второго условия скорее нет смысла включать в индекс.
В этом случае (индекс только по первому полю) я думаю, что простой запрос с 2 условиями всё равно окажется эффективнее варианта с подзапросом. Потому что выполнит ровно то же самое, но без материализации (пусть и в памяти) субвыборки по первому полю. При условии, конечно, что оптимизатор нигде не накосячит.
...
Рейтинг: 0 / 0
Ручной порядок
    #39077624
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinamiksoftБывает, что одно условие выбирает одну запись из миллиона, а второе каждую вторую. Тогда поле для второго условия скорее нет смысла включать в индекс.
В этом случае (индекс только по первому полю) я думаю, что простой запрос с 2 условиями всё равно окажется эффективнее варианта с подзапросом. Потому что выполнит ровно то же самое, но без материализации (пусть и в памяти) субвыборки по первому полю. При условии, конечно, что оптимизатор нигде не накосячит.Сильно зависит от конкретной ситуации. Если индекса в кэше нет (не использовался ранее, был вымыт оттуда или вообще не влезает), то может оказаться выгоднее десяток лишних раз слазить в таблицу, нежели читать с диска индекс удвоенного размера. Конечно, это тяжело прогнозировать и часто приходится выяснять методом проб.
...
Рейтинг: 0 / 0
Ручной порядок
    #39077797
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix
Код: sql
1.
2.
3.
4.
5.
/* первый вариант */
select * from (select * from t where a = 1) x where b = 1;

/* второй вариант */
select * from (select * from t where b = 1) x where a = 1;


Вопрос: Существует ли разница между этими двумя запросами с точки зрения внутреннего выполнения?

Суть (откуда ноги у вопроса растут): если мы точно знаем, что одно условие существенно сужает подмножество и разумнее выполнить его первым, а уже последующими условиями ковыряться в сильно уменьшенном подмножестве, чем ковыряться сразу во всей базе, а затем сужать уже отковыренное подмножество...


Уплощаем запрос:
Код: sql
1.
2.
3.
select * from (select * from t where b = 1) x where a = 1;
-- ==
select * from where b = 1 and a = 1;



Д/З: попробуй уплощить второй запрос и найти разницу между двумя запросами после этого.
...
Рейтинг: 0 / 0
Ручной порядок
    #39077800
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix
Суть (откуда ноги у вопроса растут): если мы точно знаем, что одно условие существенно сужает подмножество и разумнее выполнить его первым, а уже последующими условиями ковыряться в сильно уменьшенном подмножестве, чем ковыряться сразу во всей базе, а затем сужать уже отковыренное подмножество...



Ты предполагаешь, что последовательность выполнения частей запроса зависит от структуры этого запроса.
Твоё предположение ошибочно. Последовательность выполнения частей запроса зависит от того, как сработал оптимизатор и какой план он построил.
...
Рейтинг: 0 / 0
Ручной порядок
    #39077932
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivТы предполагаешь, что последовательность выполнения частей запроса зависит от структуры этого запроса.
Твоё предположение ошибочно. Последовательность выполнения частей запроса зависит от того, как сработал оптимизатор и какой план он построил.

Да, я в курсе, что sql - это декларативный язык.
И я понимаю, что where a = 1 && b = 1 и where b = 1 && a = 1 - это одно и то же.

В данном случае я хотел узнать, игнорит ли мускул вложенность запросов или он обращает на это внимание и сначала выполняет "внутренние" запросы, а затем все более "внешние".

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

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
/* первый вариант */
select * from (select * from t where a = 1) x where b = 1;

/* второй вариант */
select * from (select * from t where b = 1) x where a = 1;

/* исходный вариант в продакшене */
select * from t where a = 1 && b = 1;


Я прекрасно понимаю, что все эти три запроса дают один и тот же результат и мне было забавно получить советы "упростить" запрос.))))
...
Рейтинг: 0 / 0
Ручной порядок
    #39077943
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix,

А Вы планы этих запросов смотрели? Они разные/одинаковые?
...
Рейтинг: 0 / 0
Ручной порядок
    #39077972
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftА Вы планы этих запросов смотрели? Они разные/одинаковые?

Все три плана очень сильно отличаются.
Планы для вложенных запросов двухстрочные primary + derived
План для запроса без вложения однострочный simple.
...
Рейтинг: 0 / 0
Ручной порядок
    #39077978
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixИ я понимаю, что where a = 1 && b = 1 и where b = 1 && a = 1 - это одно и то же.


Ты всё время пишешь && , в то время как нужно писать AND .
...
Рейтинг: 0 / 0
Ручной порядок
    #39077982
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixВ данном случае я хотел узнать, игнорит ли мускул вложенность запросов или он обращает на это внимание и сначала выполняет "внутренние" запросы, а затем все более "внешние".



На все такие вопросы тебе могут ответить два источника данных:
напечатанный план запроса

исходный код MySQL

Если ты хочешь выработать для себя правила, как лучше писать запросы, то вот они (в первом приближении):

-- не делай лишних подзапросов, если без этого никак. В том числе, не делай подзапросы во фразе FROM, если это не необходимо.
-- формулируй запрос в каноническом виде SELECT ... FROM t1 JOIN t2 ... LEFT JOIN t3 ... where ... [group by ... [having ]]
-- условия выборки пиши в WHERE
-- условия JOIN-ов -- в JOIN-ах во фразе ON.
-- используй параметры запросов.

может что-то ещё, но это -- основное.
...
Рейтинг: 0 / 0
Ручной порядок
    #39078009
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivТы всё время пишешь && , в то время как нужно писать AND .

А собственно what's the problem?
У нас в продакшене весь мускульный код с ампрессандами...

MasterZivНа все такие вопросы тебе могут ответить два источника данных:
напечатанный план запроса



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

MasterZivНа все такие вопросы тебе могут ответить два источника данных:
исходный код MySQL



На это, если честно, яиц не хватает. :-))))
Не осилю я такое...
Такие занятия - это для совсем головастиков, а я к таким не отношусь...
Всякие итмошники таких как мы называют быдлокодеры))))
И не без оснований, кстати)))
Но мы не обижаемся...
Я отлично понимаю что такое супер-пупер программист и более чем понимаю, что таким как я до них как до парижа раком...)))
а те, кто считает себя супер-пупер, то как правило 15 минут общения с ними бывает достаточно чтобы понять, что они просто ни разу в жизни не видели живого супер-пупера, вот и строят из себя звезду россии...
а все реальные супер-пуперы они не высовываются и особо на свет не лезут...)))

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

MasterZivЕсли ты хочешь выработать для себя правила, как лучше писать запросы, то вот они (в первом приближении):


неее... я так не смогу...
я никогда не пользуюсь правилами, если их не понимаю...

MasterZiv-- не делай лишних подзапросов, если без этого никак. В том числе, не делай подзапросы во фразе FROM, если это не необходимо.


почему нет?
понятно, что когда на каждую запись основного запроса каждый вызов подзапроса пробегает всю базу заново...
но если как в примере запросов этой темы, я никого "криминала" не вижу вообще...

MasterZiv-- формулируй запрос в каноническом виде SELECT ... FROM t1 JOIN t2 ... LEFT JOIN t3 ... where ... [group by ... [having ]]

вообще непонятное правило...
я например, не знаю что такое неканонический вид...
я не понимаю это правило, потому что не знаю других форм селектов...
я реально не знаю как ещё можно это написать)))
ну не стану же я делать запрос from t selec * where join order group )))
оно просто выполняться не будет...)))

MasterZiv-- условия выборки пиши в WHERE
-- условия JOIN-ов -- в JOIN-ах во фразе ON.

Чтобы я эти правила стал выполнять, мне сначала важно понять какие потери мы несем при размещении условий выборок в джоин-секции

MasterZiv-- используй параметры запросов.

Не понял этот пункт вообще...
...
Рейтинг: 0 / 0
Ручной порядок
    #39078021
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixкакие потери мы несем при размещении условий выборок в джоин-секцииДля OUTER JOIN-ов - изменение логики (и результата) запроса. Для INNER JOIN-ов - затруднение сопровождаемости.
...
Рейтинг: 0 / 0
Ручной порядок
    #39078030
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftLumixкакие потери мы несем при размещении условий выборок в джоин-секцииДля OUTER JOIN-ов - изменение логики (и результата) запроса.

Можете привести какой-нибудь пример на пальцах?
Вот тут по-вашему логика меняется или нет?

Код: sql
1.
2.
select * from a left join b on a.id = b.id where b.tit = 'some';
select * from a left join b on a.id = b.id && b.tit = 'some';



miksoftLumixкакие потери мы несем при размещении условий выборок в джоин-секцииДля INNER JOIN-ов - затруднение сопровождаемости.

А это что имеется ввиду?
Можете какой-нибудь пример на пальцах?
...
Рейтинг: 0 / 0
Ручной порядок
    #39078035
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixМожете привести какой-нибудь пример на пальцах?
Вот тут по-вашему логика меняется или нет?

Код: sql
1.
2.
select * from a left join b on a.id = b.id where b.tit = 'some';
select * from a left join b on a.id = b.id && b.tit = 'some';

Да, конечно, меняется. Тут условие where b.tit = 'some' фактически превращает left join в просто join.
...
Рейтинг: 0 / 0
Ручной порядок
    #39078037
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumixmiksoftпропущено...
Для INNER JOIN-ов - затруднение сопровождаемости.

А это что имеется ввиду?
Можете какой-нибудь пример на пальцах?Другой разработчик, который потом будет читать этот запрос, имеет все основания полагать, что в секции WHERE он увидит все условия для фильтрации. И он не будет ожидать, что часть из них спряталась в секции FROM. Если это запрос строк эдак на 200, то это становится проблемой. А я и в пяти строчках могу ошибиться таким образом :)
...
Рейтинг: 0 / 0
Ручной порядок
    #39078062
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftLumixМожете привести какой-нибудь пример на пальцах?
Вот тут по-вашему логика меняется или нет?

Код: sql
1.
2.
select * from a left join b on a.id = b.id where b.tit = 'some';
select * from a left join b on a.id = b.id && b.tit = 'some';

Да, конечно, меняется. Тут условие where b.tit = 'some' фактически превращает left join в просто join.

Oк, согласен.
А как насчет такого?

Код: sql
1.
2.
select * from a left join b on a.id = b.id where a.tit = 'some';
select * from a left join b on a.id = b.id && a.tit = 'some';



или вы хотите сказать, что как только мускул увидит условие a.tit = 'some', то он тут же сам включит inner??
...
Рейтинг: 0 / 0
Ручной порядок
    #39078066
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixА как насчет такого?

Код: sql
1.
2.
select * from a left join b on a.id = b.id where a.tit = 'some';
select * from a left join b on a.id = b.id && a.tit = 'some';

Эти запросы логически эквивалентны.
Хотя второй из них имеет настолько непривычный вид, что вызывает отторжение.
Lumixили вы хотите сказать, что как только мускул увидит условие a.tit = 'some', то он тут же сам включит inner??Нет, это только для "необязательной" стороны JOIN-а.
...
Рейтинг: 0 / 0
Ручной порядок
    #39078068
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftLumixпропущено...


А это что имеется ввиду?
Можете какой-нибудь пример на пальцах?Другой разработчик, который потом будет читать этот запрос, имеет все основания полагать, что в секции WHERE он увидит все условия для фильтрации. И он не будет ожидать, что часть из них спряталась в секции FROM. Если это запрос строк эдак на 200, то это становится проблемой. А я и в пяти строчках могу ошибиться таким образом :)

Практика показала, что ваши опасения надуманны.
По крайней мере в нашем деле.

Та опасность, о которой вы сейчас пишите, актуальна только для слепой разработки, то есть когда программист пишет код, тестят тестеры (другие люди), а юзают вообще третьи, то есть пользователи второго и третьего порядка.

В нашем деле разработчики пишут не код, а продукт и поэтому они контроллируют не как у них работает код, а как у них работает полезная функция, то есть конечный продукт.

И поэтому как показала практика, подобные опасения беспочвенны.
Если они куда-то что-то вставят не так, то у них просто софт не будет работать как этого ожидает заказчик и они это увидят прямо во время разработки.

PS. В наших проектах не существует запросов на 200 строк.
Просто архитектура платформы так устроена, что подобные запросы физически никогда не требуются.
К тому же наши разработчики практически не лазят в sql...
Очень-очень редко, когда дело доходит до живого sql...
Это очень-очень редко...
...
Рейтинг: 0 / 0
Ручной порядок
    #39078069
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftLumixА как насчет такого?

Код: sql
1.
2.
select * from a left join b on a.id = b.id where a.tit = 'some';
select * from a left join b on a.id = b.id && a.tit = 'some';

Эти запросы логически эквивалентны.
Хотя второй из них имеет настолько непривычный вид, что вызывает отторжение.
Lumixили вы хотите сказать, что как только мускул увидит условие a.tit = 'some', то он тут же сам включит inner??Нет, это только для "необязательной" стороны JOIN-а.

Ну вот, получается что вывод по этому пункту такой: я не вижу "криминала" в использовании условий в join-секции...
...
Рейтинг: 0 / 0
Ручной порядок
    #39078071
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LumixНу вот, получается что вывод по этому пункту такой: я не вижу "криминала" в использовании условий в join-секции...Ну если ваши разработчики не читают код SQL, то да, для вас этого "криминала" не существует. Но так не у всех.
...
Рейтинг: 0 / 0
Ручной порядок
    #39078097
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftLumixНу вот, получается что вывод по этому пункту такой: я не вижу "криминала" в использовании условий в join-секции...Ну если ваши разработчики не читают код SQL, то да, для вас этого "криминала" не существует. Но так не у всех.

Читают они, читают.
И платформа позволяет творить любые чудеса с чистым sql.
Просто реально за много лет до сих пор не было ничего на 200 строк
И много лет уже пользуемся простановкой условий в джоин-секции и пока "никто не умер"))
...
Рейтинг: 0 / 0
Ручной порядок
    #39078128
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://www.codersrevolution.com/blog/MySQL-performance-INNER-JOIN-vs-subselect

попалась под руки статья, где чувак засовывая условия в джоин-секцию увеличил время запроса в 30 раз при объеме несколько сотен тысяч записей в одной таблице и несколько десятков тысяч в другой таблице.
...
Рейтинг: 0 / 0
Ручной порядок
    #39078149
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix http://www.codersrevolution.com/blog/MySQL-performance-INNER-JOIN-vs-subselect

попалась под руки статья, где чувак засовывая условия в джоин-секцию увеличил время запроса в 30 раз при объеме несколько сотен тысяч записей в одной таблице и несколько десятков тысяч в другой таблице.Там совсем о другом. Дело не в секции JOIN, а в том, что конструкция IN (SELECT ...) оптимизатором ошибочно всегда считается как зависимый подзапрос. В результате чего подазпрос выполняется столько раз, сколько раз нужно проверить условие IN, т.е. по числу записей. Во времена этот статьи все версии MySQL были подвержены этому багу. Исправлено только в версии 5.6.
...
Рейтинг: 0 / 0
Ручной порядок
    #39078154
Фотография Lumix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoft, ok!

Просто я на этом примере хотел показать новичкам, которые читают этот форум, что не стоит бояться совать условия в джоин-секцию. И эту статью я привел в качестве примера, ведь серьезный взрослый чувак сует в джоин-секцию и пускает это в продакшен, значит, особого криминала в этом нет...
...
Рейтинг: 0 / 0
Ручной порядок
    #39078193
retvizan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot Lumix]MasterZivВ данном случае я хотел узнать, игнорит ли мускул вложенность запросов или он обращает на это внимание и сначала выполняет "внутренние" запросы, а затем все более "внешние".Зависит от версии.
...
Рейтинг: 0 / 0
Ручной порядок
    #39078465
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Lumix http://www.codersrevolution.com/blog/MySQL-performance-INNER-JOIN-vs-subselect

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

это как дать слепому пощупать жопу слона: "Слон теплый и круглый" - будет вывод. Так же и в таких статьях.
...
Рейтинг: 0 / 0
30 сообщений из 30, показаны все 2 страниц
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Ручной порядок
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]