2011-11-15 22 views
1

想象一下,你有這3個表:我如何加快這個簡單的查詢?

enter image description here

而且想象有根據該架構的海量數據。

當我運行這樣的查詢:

SELECT DISTINCT tPerson.Name, tPerson.Town 
FROM tPerson 
JOIN tPersonTypeCodeMap ON tPersonTypeCodeMap.PersonId = tPerson.Id 
JOIN tPersonHobbyCodeMap ON tPersonHobbyCodeMap.PersonId = tPerson.Id 
WHERE tPersonTypeCodeMap.TypeCode IN ('C', 'S', 'P') 

它的工作原理相當快!

但是當我添加第二個條件(NOT IN)查詢需要年齡:

SELECT DISTINCT tPerson.Name, tPerson.Town 
FROM tPerson 
JOIN tPersonTypeCodeMap ON tPersonTypeCodeMap.PersonId = tPerson.Id 
JOIN tPersonHobbyCodeMap ON tPersonHobbyCodeMap.PersonId = tPerson.Id 
WHERE tPersonTypeCodeMap.TypeCode IN ('C', 'S', 'P') 
OR tPersonHobbCodeMap.HobbyCode NOT IN ('SKATE','CLIMBING') 

你能告訴我什麼是減慢查詢,我怎麼可以讓它運行得更快的原因是什麼?

+1

是否有typecode上的索引而不是hobbycode上的索引? – Maess

回答

2

在第一個查詢中,大多數過濾可以通過僅查看一個表(tpersonTypeCodeMap)來完成。在第二個示例中,需要連接兩個表以執行過濾。此外,一旦您引入「或」,您將失去任何索引的影響。

是不是真的你想在這兩個過濾器上操作「OR」,而不是「AND」?另外,您是否確實希望每個人返回多個記錄,具體取決於他們匹配的TypeCodes數量以及他們失敗匹配的HobbyCodes數量?

如果條件「或」,其實,你想要什麼,你可以使用:

SELECT tPerson.Name, tPerson.Town 
FROM tPerson JOIN tPersonTypeCodeMap 
    ON tPersonTypeCodeMap.PersonId = tPerson.Id 
WHERE tPersonTypeCodeMap.TypeCode IN ('C', 'S', 'P') 
UNION 
SELECT tPerson.Name, tPerson.Town JOIN tPersonHobbyCodeMap 
     ON tPersonHobbyCodeMap.PersonId = tPerson.Id 
WHERE tPersonHobbCodeMap.HobbyCode NOT IN ('SKATE','CLIMBING') 

這將獲得兩套獨立的記錄,然後UNION在一起。通過使用UNION而不是UNION ALL,將返回DISTINCT操作以將數據庫減少爲唯一行。

+0

我編輯了問題,加入了'DISTINCT' – pencilCake

+0

而且,我需要OR,因爲我不想使用EXCEPT。所以我倒置了一個以OR操作符結束的條件。 – pencilCake

+0

我喜歡UNION的想法!所以它使整個查詢工作更快的主要原因是要篩選的記錄數是一個SELECT通過將其分解爲2來減少? – pencilCake

0

NOT IN部分表現不佳。試試這個版本。

SELECT tPerson.Name, tPerson.Town 
FROM tPerson 
JOIN tPersonTypeCodeMap ON tPersonTypeCodeMap.PersonId = tPerson.Id 
WHERE tPersonTypeCodeMap.TypeCode IN ('C', 'S', 'P') 
OR NOT EXISTS(SELECT NULL 
        FROM tPersonHobbCodeMap 
        WHERE tPersonHobbCodeMap.PersonId = tPerson.id 
         AND tPersonHobbCodeMap.HobbyCode IN ('SKATE','CLIMBING')) 
+0

@Joe:請你解釋爲什麼它不能很好地運行的原因? – pencilCake

+0

這不會優化到同樣的事情? –

+0

@pencilCake和Larry:請參閱[NOT IN VS NOT EXISTS](http://sqlserverpedia.com/blog/sql-server-bloggers/not-exists-vs-not-in/) –