2015-02-11 53 views
0

我知道我下面的查詢僅僅是可怕的,它需要2分鐘得到10條記錄(清單表中有超過雖然1M記錄),但我不知道什麼是更好的方式來寫這個內有加入不同慢

我只是簡單地想要得到所有具有房源各國連接列表是全省表中的國家..

ALTER VIEW [dbo].[CountriesWithListings] 
AS 
SELECT  distinct  
    cn.CountryID, 
    cn.Code as CountryCode, 
    cn.Name as CountryName 
FROM   dbo.Countries AS cn 

       INNER JOIN dbo.Provinces AS p ON p.CountryID = cn.CountryID 
       INNER JOIN dbo.Cities c on c.ProvinceID = p.ProvinceID 
       INNER JOIN dbo.Listings AS l ON l.CityID = c.CityID 

WHERE l.IsActive = 1 AND l.IsApproved = 1 
+0

確實包括數據庫名稱和版本。 – 2015-02-11 16:04:24

+0

另外,如果您在標題中建議distinct是一個問題,那麼您還需要爲查詢包含一個'EXPLAIN',那麼沒有DISTINCT的行數將是最小值。 – 2015-02-11 16:06:56

+1

刪除不同的,僅從dbo.Countries中選擇,然後將其餘部分移至EXISTS。 – jarlh 2015-02-11 16:07:42

回答

2

假設您有適當的指數,使用distinct是昂貴的。您應該能夠使用exists,以獲得更好的性能:

SELECT  
    cn.CountryID, 
    cn.Code as CountryCode, 
    cn.Name as CountryName 
FROM dbo.Countries AS cn 
WHERE EXISTS (
    SELECT 1 
    FROM dbo.Provinces AS p 
       INNER JOIN dbo.Cities c on c.ProvinceID = p.ProvinceID 
       INNER JOIN dbo.Listings AS l ON l.CityID = c.CityID 
    WHERE p.CountryID = cn.CountryID 
     AND l.IsActive = 1 
     AND l.IsApproved = 1 
) 
+0

這工作完美,將在8分鐘內標記答案,當它允許我。 – Zoinky 2015-02-11 16:09:39

0

是上市表索引?如果它有1M條目,最好先索引它,然後檢查性能。您的查詢不是那麼複雜

0

查詢的性能還取決於存在於你的環境,你所使用的列的索引。

嘗試......

SELECT cn.CountryID 
    ,MIN(cn.Code) AS CountryCode 
    ,MIN(cn.NAME) AS CountryName 
FROM dbo.Countries AS cn 
INNER JOIN dbo.Provinces AS p ON p.CountryID = cn.CountryID 
INNER JOIN dbo.Cities c ON c.ProvinceID = p.ProvinceID 
INNER JOIN dbo.Listings AS l ON l.CityID = c.CityID 
WHERE l.IsActive = 1 
    AND l.IsApproved = 1 
GROUP BY cn.CountryID 
+0

爲什麼DISTINCT和GROUP BY? – jarlh 2015-02-11 16:12:59

+0

@jarlh在重新使用舊代碼時,沒有改變那部分內容。謝謝 – SoulTrain 2015-02-11 16:15:19

+0

歡迎您! (不要認爲它很重要,應該優化,但是這樣看起來更好!) – jarlh 2015-02-11 16:16:28

0

無需添加索引或其他性能調整這個查詢應該跑得更快:

ALTER VIEW [dbo].[CountriesWithListings] 
AS 
    SELECT cn.CountryID, cn.Code as CountryCode, cn.Name as CountryName 
    FROM dbo.Countries AS cn 
    WHERE cn.CountryID IN 
    (
     SELECT p.CountryId FROM dbo.Provinces 
     INNER JOIN dbo.Cities c on c.ProvinceID = p.ProvinceID 
     INNER JOIN dbo.Listings AS l ON l.CityID = c.CityID 
     WHERE l.IsActive = 1 AND l.IsApproved = 1 
    )