SQL Server查询优化问题

问题描述:

我有以下的疑问,我很想找到一个更好的办法来做到这一点,因为它看起来不正确我这样做的方式......SQL Server查询优化问题

编辑

对不起,我没有指定我只想返回实际匹配所有设施的广告!

SELECT TOP 50 Advert.Id 
FROM Advert 
WHERE Id in(SELECT Advert_id FROM AdvertsToAmenities WHERE Amenity_id = 1 AND Advert_Id = Id) 
    AND Id in(SELECT Advert_id FROM AdvertsToAmenities WHERE Amenity_id = 3 AND Advert_Id = Id) 
    AND Id in(SELECT Advert_id FROM AdvertsToAmenities WHERE Amenity_id = 5 AND Advert_Id = Id) 

-- OR -- 

SELECT TOP 50 Advert.Id 
FROM Advert 
JOIN AdvertsToAmenities a on Advert.Id = a.Advert_id 
JOIN AdvertsToAmenities b on Advert.Id = b.Advert_id 
JOIN AdvertsToAmenities c on Advert.Id = c.Advert_id 
WHERE a.Amenity_id = 1 
    AND b.Amenity_id = 3 
    AND c.Amenity_id = 5 

我想知道如何优化这些查询!

+1

“要做到这一点” - 你能不能给我们一个很好的解决问题的说明,而不必大家一起读书的问题解析查询? – Oded 2011-04-19 15:24:56

+1

看起来你的问题与你的评论不一样。请记住,SQL Server从查询中派生出的执行路径是高度优化的,尽管您声明SQL的顺序方式。可能需要检查实际执行计划以确定是否需要进一步优化。 如果你指的是让sql更易读易懂,那么显然有改进的余地。我会试着拿出一个例子。 – 2011-04-19 15:27:24

+0

此外,您可能会发现表格中体面的索引/键会比重新编写查询有更戏剧性的“优化”结果。 – 2011-04-19 15:30:14

您的问题对我来说看起来不错。另一种方法是使用这样的:

SELECT TOP 50 Advert.Id 
    FROM Advert JOIN AdvertsToAmenities a ON Advert.Id = a.Advert_id 
WHERE a.Amenity_id = 1 
    OR a.Amenity_id = 3 
    OR a.Amenity_id = 5 
GROUP BY Advert.Id 
HAVING COUNT(DISTINCT a.Amenity_id) = 3 

如果(Advert_Id, Amenity_id)对都是独一无二的,你可以删除DISTINCT

+0

+1 - 我认为他的原稿也不错。 – JNK 2011-04-19 15:27:31

你的查询如何重组,可以让你简单地创建一个逗号分隔的特定设施ID的列表?

SELECT TOP 50 
a.[ID] 
FROM [Advert] a 
INNER JOIN 
(
    SELECT ata.[Advert_ID] 
    FROM [AdvertsToAmenities] ata 
    WHERE ata.[Amenity_ID] 
    IN (1, 3, 4, 5) -- Your list of amenity IDs 
) as ata 
ON a.[ID] = ata.[Advert_ID] 

这使用动态表语句在与广告列表进行回合之前仅对那些适用的设施进行预先过滤。请注意,Sql Server将在执行之前大量优化子查询。这应该意味着您将得到Sql Server提供的所有优化的更多可维护语句的好处。

+0

我只想返回他们在列表中具有*全部*设施的广告。在您的查询中,它将返回至少有一个*列表中的设施的广告。 – superlogical 2011-04-21 07:33:14

*试试这个简单的*

SELECT TOP 50 a.Id 
FROM Advert a, AdvertsToAmenities b 
WHERE a.Amenity_id in ('1','3','5') 
and a.Id = b.Amenity_id