2017-01-03 96 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分析和有關表的大小,指數,當前時間的一些信息表現,慾望時間等。慢是一個相對術語,我們需要真正的價值來比較。 MySQL也請讀[How-to-Ask](http://stackoverflow.com/help/how-to-ask) – e4c5

+2

在我看來,你的表沒有被正確地規範化,因爲多行跨越一個單獨的邏輯實體(取決於該域)。另外,如果任何行有'is_verified = 1',只有最新的'added'入口計數或是一個域驗證? – 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

你有'域'和'添加'的索引嗎?這種查詢應該在幾毫秒內返回結果。看看'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 JOINNULL檢查:

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

相關問題