#mysql #sql #database #performance #select
#mysql #sql #База данных #Производительность #выберите
Вопрос:
select a , b , c
from h1 where a in
(
select a
from h1
group by a
having count(distinct b) = 1
)
Ответ №1:
Наиболее эффективным методом должно быть not exists
:
select h.a, h.b, h.c
from h1 h
where not exists (select 1
from h1 hh
where hh.a = h.a and hh.b <> h.b
);
Для повышения производительности вам нужен индекс на h1(a, b)
.
Агрегирование не требуется.
Ответ №2:
Я предлагаю добавить следующий индекс в вашу таблицу:
CREATE INDEX idx ON h1 (a, b, c);
Затем перепишите свой запрос следующим образом:
SELECT a, b, c
FROM h1 t1
WHERE EXISTS
(
SELECT 1
FROM h1 t2
WHERE t1.a = t2.a
GROUP BY t2.a
HAVING MIN(t2.b) = MAX(t2.b)
);
В идеале индекс позволит MySQL довольно быстро оценить подзапрос агрегации. Обратите внимание, что трюк min / max говорит то же самое, что и требование, чтобы значение distinct count было равно 1. За исключением этой версии, может использоваться индекс.
Комментарии:
1. можете ли вы сделать так, чтобы этот файл также выбирал a, b, c ИЗ (ВЫБЕРИТЕ a, b, c, d ИЗ h1, где a в ( выберите a из группы h1, имея количество (отличное от b) = 1 ))
2. @jais Настройка запроса часто выполняется по одному разу. Возможно, вы захотите открыть новый вопрос.
Ответ №3:
вы могли бы попробовать использовать exists, в случае, если подзапрос возвращает большой набор данных, это может работать лучше, чем в
select a , b , c
from h1 t1 where exists
(
select 1
from h1 t2
t2.a=t1.a
having count(distinct b) = 1
)
Комментарии:
1. Большинство баз данных будут оптимизировать
WHERE IN
иWHERE EXISTS
для того же самого.2. ОШИБКА: Синтаксическая ошибка: обнаружено «t2» в строке 17, столбец 5. Код ошибки: 3000
Ответ №4:
IN ( SELECT ... )
может быть ужасно медленным. Помимо использования EXISTS(...)
, иногда полезно использовать «производную таблицу»:
select h1.a , h1.b , h1.c
FROM
(
SELECT a
from h1
group by a
having count(distinct b) = 1
) AS x
JOIN h1 USING(a)