SQL (любой) запрос для понимания оптимизации запросов - PullRequest
0 голосов
/ 15 мая 2009

У меня особенно медленный запрос из-за огромного количества информации, объединяемой вместе. Однако мне нужно было добавить предложение where в форме идентификатора (выберите идентификатор из таблицы).

Я хочу знать, есть ли какой-нибудь выигрыш от следующего, и более настойчивый, даст ли он даже желаемые результаты.

select a.* from a where a.id in (select id from b where b.id = a.id)

как альтернатива:

select a.* from a where a.id in (select id from b)

Обновление: MySQL Не могу быть более конкретным извините Таблица А - это объединение 7 разных таблиц. использование * для примера

Редактировать, b не выбран

Ответы [ 7 ]

2 голосов
/ 15 мая 2009

Оба перечисленных вами запроса эквивалентны:

select a.* 
from a 
inner join b on b.id = a.id

Почти все оптимизаторы будут выполнять их одинаково.

Вы можете опубликовать реальный план выполнения, и кто-то здесь может дать вам способ ускорить его. Помогает указать, какой сервер базы данных вы используете.

2 голосов
/ 15 мая 2009

Ваш вопрос был о разнице между этими двумя:

select a.* from a where a.id in (select id from b where b.id = a.id)

select a.* from a where a.id in (select id from b)

Первый - это коррелированный подзапрос. Это может заставить MySQL выполнить подзапрос для каждой строки a.

Последний является некоррелированным подзапросом. MySQL должен иметь возможность выполнить его один раз и кэшировать результаты для сравнения с каждой строкой a.

Я бы использовал последнее.

0 голосов
/ 15 мая 2009

Ваша проблема, скорее всего, в семи таблицах в пределах "a"

сделать таблицу FROM "a.id" сделать следующее соединение: внутреннее соединение b на a.id = b.id

затем включите остальные шесть таблиц.

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

0 голосов
/ 15 мая 2009
Select a.* from a
inner join (Select distinct id from b) c
on a.ID = c.AssetID

Я перепробовал все 3 версии, и они работали примерно одинаково. План выполнения был таким же (внутреннее соединение, IN (с и без предложения where в подзапросе), Exists)

Поскольку вы не выбираете какие-либо другие поля из B, я предпочитаю использовать Where IN (Выбрать ...). Кто-нибудь взглянет на запрос и узнает, что вы пытаетесь сделать (Показывать только в a, если в b. ).

0 голосов
/ 15 мая 2009

Вы смотрели на план выполнения?

Как насчет

select a.* 
from a 
inner join b
on a.id = b.id

предположительно, поля id являются первичными ключами?

0 голосов
/ 15 мая 2009

Я бы никогда не использовал подобный подзапрос. Объединение будет намного быстрее.

select a.*
from a 
join b on a.id = b.id

Конечно, также не используйте select * (особенно никогда не используйте его при выполнении объединения, поскольку хотя бы одно поле повторяется), и это тратит ресурсы сети на отправку ненужных данных.

0 голосов
/ 15 мая 2009

YMMV, но я часто обнаруживал, что использование EXISTS вместо IN ускоряет запросы.

SELECT a.* FROM a WHERE EXISTS (SELECT 1 FROM b WHERE b.id = a.id)

Конечно, без просмотра остальной части запроса и контекста это может не ускорить выполнение запроса.

Присоединение может быть более предпочтительным вариантом, но если a.id появится более одного раза в столбце id в b, вам придется добавить туда DISTINCT, и вы, скорее всего, вернетесь назад с точки зрения оптимизации.

...