2015-02-11 55 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 
    )