2017-01-03 4 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; 

この要求の背後にある主要なアイデアはis_verifiedを持っていないすべてのdomainを得ることです本当に。

上記の例では、「example.com」は1回だけ返されます。

リクエストは正常ですが、実行に時間がかかります(私は何千ものエントリがあります)。この要求を行うための他の方法が、より高速かつ効率的になるのでしょうか?

+1

パフォーマンスの問題がEXPLAIN含めるべきでは分析して、テーブルのサイズ、インデックス、現在の時刻に関する情報パフォーマンス、欲求時間などが含まれます。遅いというのは相対的な用語であり、比較するには実際の値が必要です。また、[How-to-Ask](http://stackoverflow.com/help/how-to-ask)をお読みください。 – e4c5

+2

私の目では、複数の行が1つの論理エンティティにまたがっているため、テーブルが正しく正規化されていません。ドメイン)。また、最新の 'added'エントリカウントだけ、または' 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

私はあなたのコマンドを実行しました.180分以上実行するのに1分6秒かかりました。もう一方の応答は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それを指摘してくれてありがとう、私は確かに異なる質問を理解した。修正しましたが、私は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つは実行するのに1分6秒かかりました、あなたはまだ10分後に動いています。ご協力ありがとうございました! @CyrilN。 –

+0

。あなたのテーブルに 'domain'と' is_verified'カラムのインデックスがありますか?このクエリは、(テーブルが適切にインデックスされている場合のみ)すべての 'GROUP BY'クエリよりもはるかに高速でなければなりません。 – axiac

関連する問題