2012-10-08 12 views
3

實施例的數據集:優化一個SQL查詢標籤匹配

id | tag 
---|------ 
1 | car 
1 | bike 
2 | boat 
2 | bike 
3 | plane 
3 | car 

idtag都編入索引。

我想獲得與標籤[汽車,自行車]相匹配的標識(標籤數量可以不同)。

一個天真的查詢,這樣做將是:

SELECT id 
FROM test 
WHERE tag = 'car' 
    OR tag = 'bike' 
GROUP BY id 
HAVING COUNT(*) = 2 

但是,這樣做是因爲該集團與事實相符一個標籤,任何線被考慮到該組的效率非常低(和我有一個大容量)。

是否有更有效的查詢這種情況?

我看到的唯一的解決辦法是有一個包含像另一個表:

​​

但這不是實現和維護最新的一個簡單的解決方案。

其他相關信息:

  • 名稱匹配必須是精確的(沒有全文索引)
  • 標籤的數量並不總是2
+0

你的問題很好的介紹。與[SQLFiddle](http://sqlfiddle.com)例如它將是完美的:) –

+2

我會開始規範化你的標籤。你應該有一個ID和名稱的標籤表。那麼你上面的數據集就是id,TagID – Tobsey

+0

,所以在這種情況下,結果是汽車和自行車,因爲它們都有兩行的名字? – Diego

回答

0

試試這個:

SELECT id 
FROM test 
WHERE tag in('car','bike') 
GROUP BY id 
HAVING COUNT(*) = 2 

並在標籤列上創建非聚集索引

+2

'IN'是'OR'的同義詞。這沒有什麼區別。 – podiluska

+1

實際上IN比OR快OR – AnandPhadke

+0

我沒有想到'IN'的確,你們有沒有鏈接來支持這兩種可能性(快或者不快)? –

-1

不知道如果我得到你,但試試這個:

select tag, count(*) as amount 
into #temp 
from MYTABLE 
group by tag 


select t1.tag 
from #temp t1 join #temp t2 on t1.amount=t2.amount and t1.tag=t2.tag and t1.amount=2 

應導致自行車和汽車,因爲它們都具有2行,whihc等於2

+0

我想優化查詢,你的做法似乎沒有更高效? –

+0

我認爲它值得一試,並比較計劃。 – Diego

0

在這裏你去:

select id from TEST where tag = 'car' and ID in (select id from TEST where tag='bike') 
+0

來自OP:「標籤數量不總是2」 –

+0

是的,但是您可以用更多的「ID in」擴展查詢。你已經必須在查詢中做一些「知道要搜索多少東西」。在這個例子中,你可以使用乾淨的索引而不需要任何分組並且有數量。 – Romo

+0

可以投票給它,但請分析查詢與答案中的其他示例。你會更快。不管你怎麼做,你仍然需要「查詢」查詢中有多少「標籤」(汽車,自行車等)。 – Romo