Б>SELECT a, t
Б>FROM (
Б> SELECT a, x as t FROM TableA
Б> UNION
Б> SELECT a, y as t FROM TableB)
Б>WHERE a < :p1 AND a > :p2
Б>
Б>Вроде ж понятно, что операцию WHERE лучше применить сначала к TableA и TableB (используя индексы), а потом уже делать UNION.
А вот непонятно. Where по правилам синтаксиса относится к последнему select, а не ко всем. Что логично, ибо как отделить общий для всех where от специфичного для таблицы?
Здравствуйте, Буравчик, Вы писали:
Б>Mysql не смог оптимизировать такой запрос: Б>Не ожидал такого. Это нормально для оптимизатора БД не разобраться в этой ситуации?
Здравствуйте, Буравчик, Вы писали:
Б>В таблицах TableA и TableB есть индексы по полю 'a'. Б>Mysql не смог оптимизировать такой запрос:
Б>Вроде ж понятно, что операцию WHERE лучше применить сначала к TableA и TableB (используя индексы), а потом уже делать UNION.
Б>Если ему явно указать WHERE для каждой таблицы, то все работает быстро.
если UNION на UNION ALL заменить, ничего не поменяется?
Здравствуйте, Sharov, Вы писали:
S>А вот непонятно. Where по правилам синтаксиса относится к последнему select, а не ко всем. Что логично, ибо как отделить общий для всех where от специфичного для таблицы?
В данном случае автор использует derived table, т.е. вложенный запрос, заключенный в круглые скобки (...) Именно поэтому where относится ко всему запросу, а не только к последнему после union.
Здравствуйте, Буравчик, Вы писали:
Б>Не ожидал такого. Это нормально для оптимизатора БД не разобраться в этой ситуации?
Все определяется конкретной СУБД. В MySQL это реализовано описанным вами способом, а SQL Server например, в независимости от места нахождения условий, сначала выполнит поиск, а потом объединит данные. Проверенный факт.
Здравствуйте, Буравчик, Вы писали:
Б>Для table1 применяется индекс, а для table2 — нет. Интересно... Б>Индекс построен по полю m (+еще несколько полей), поле m2 в индексе отсутствует
Зависит от вашей структуры и данных. Но предположу, что СУБД решила, что для получения полей m и m2 выгоднее сканирование всей таблицы, чем поиск по индексу построенному по m и уточняющие запросы для извлечения m2 для каждой записи из m. Возможно, необходимо создать покрывающий индекс, который основывался бы на полях m и m2. В SQL Server есть удобный механизм индексов со включенными столбцами. В MySQL насколько я знаю аналога нет.