2017-01-03 3 views
1

У меня есть таблица, которая содержит следующие столбцы:Есть ли более быстрый способ выполнить следующий запрос SQL?

id, name, domain, added, is_verified 
1, "First Google", "google.com", DATE(), 1 
2, "Second Google", "google.com", DATE(), 1 
3, "Third Google", "google.com", DATE(), 1 
4, "First disney", "disney.com", DATE(), 1 
5, "Second disney", "disney.com", DATE(), 1 
6, "Third disney", "disney.com", DATE(), 0 
7, "First example", "example.com", DATE(), 0 
8, "Second example", "example.com", DATE(), 0 

И следующий запрос:

SELECT domain FROM mytable WHERE domain NOT IN 
    (SELECT domain FROM mytable WHERE is_verified = 1 GROUP BY domain) 
GROUP BY domain ORDER BY added DESC; 

Основная идея этого запроса, чтобы получить все в domain, что не имеет is_verified по истине.

В приведенном выше примере это приведет только к возврату «example.com» один раз.

Запрос работает хорошо, но требуется время для выполнения (у меня есть тысячи записей). Есть ли другой способ сделать этот запрос более быстрым и эффективным?

+1

вопросы эффективности должны включать EXPLAIN ANALYZE и некоторую информация о размере таблицы, индекс, текущее время производительность, время ожидания и т. д. Медленный - относительный термин, и нам нужна реальная ценность для сравнения. MySQL также читайте [How-to-Ask] (http://stackoverflow.com/help/how-to-ask) – e4c5

+2

На мой взгляд, ваша таблица неправильно нормализована, так как несколько строк охватывают один единственный логический объект (в зависимости от домен). Кроме того, выполняется ли только последнее количество записей «добавлено» или проверено домен, если в каких-либо строках «is_verified = 1»? – Smutje

ответ

1
SELECT domain 
FROM mytable 
group by domain 
having max(is_verified) = 0 
ORDER BY max(added) DESC 

я добавил пункт order by. Вы должны решить, какую запись added вы хотите взять для каждого домена. Я выбрал максимальное добавленное значение домена.

+1

Я запустил вашу команду, и потребовалось 1 минута и 6 секунд, чтобы выполнить более 800 000 строк. Другой ответ был выполнен более 10 минут и все еще работает. Поэтому я принял ваш ответ :) Спасибо! –

+0

У вас есть индексы на 'domain' и' added'? Такой запрос должен возвращать результаты за несколько миллисекунд. Посмотрите на вывод 'explain select ...' Он сообщает вам, где он не использует индексы. –

-1

Зачем вам нужно выбрать суб-выбор? Разве это не принесет такой же результат?

SELECT domain 
    FROM mytable 
    GROUP BY domain 
    HAVING sum(is_verified)<1; 
+1

Этот запрос также возвращает 'disney.com'. – axiac

+0

@axiac Спасибо, что указали это, я действительно понял вопрос другой. Исправлено, хотя я был бы первым в acknoledge, что использование предложения HAVING является всем, кроме эффективного ... – arkascha

2

Вы можете использовать LEFT JOIN с NULL проверкой:

SELECT T1.Domain 
FROM mytable T1 
LEFT JOIN mytable T2 ON T2.domain = T1.domain AND T2.is_verified = 1 
WHERE T2.ID IS NULL 

выполнение образца с заданными данными:

DECLARE @TESTDOMAIN TABLE (id int, name varchar(100), domain varchar (100), added datetime, is_verified bit) 

insert into @testdomain (id, name, domain, added, is_verified) 
SELECT 1, 'First Google', 'google.com', GETDATE(), 1 UNION 
SELECT 2, 'Second Google', 'google.com', GETDATE(), 1 UNION 
SELECT 3, 'Third Google', 'google.com', GETDATE(), 1 UNION 
SELECT 4, 'First disney', 'disney.com', GETDATE(), 1 UNION 
SELECT 5, 'Second disney', 'disney.com', GETDATE(), 1 UNION 
SELECT 6, 'Third disney', 'disney.com', GETDATE(), 0 UNION 
SELECT 7, 'First example', 'example.com', GETDATE(), 0 UNION 
SELECT 8, 'Second example', 'example.com', GETDATE(), 0 

SELECT T1.Domain 
FROM @TESTDOMAIN T1 
LEFT JOIN @TESTDOMAIN T2 ON T2.domain = T1.domain AND T2.is_verified = 1 
WHERE T2.ID IS NULL 
+0

Хороший способ выразить это :) Я запустил оба настоящих ответа, а другой занял 1 минуту и ​​6 секунд, чтобы запустить, ваш все еще запущен через 10 минут, поэтому я принял другого. Спасибо за помощь! –

+0

@CyrilN. имеет ли ваша таблица индексы на столбцах 'domain' и' is_verified'? Этот запрос должен быть намного быстрее, чем любой запрос GROUP BY (но только если таблица правильно проиндексирована). – axiac