2012-07-24 55 views
2

我在我的数据库中有一个巨大的表,其中包含城市之间的距离。这使我的应用程序能够在选择起始城市时查找世界各地的附近城市。针对大型SQL Server表执行不同的两个类似查询

它包含4列:

ID, StartCityID, EndCityID, Distance 

,并包含大约120万行。

我有索引建立在startcityIDendcityID,另一个用于两个,每个另一个用于startcity + distance,并且endcity + distance(这是我使用索引的第一个真正的交易所以不是100%肯定,如果我做它正确)。

反正 - 我做了以下2个查询:

Select distinct StartCityID 
From Distances where EndCityID = 23485 

Select distinct EndCityID 
From Distances where StartCityID = 20045 

他们都返回相同数量的cityID的,但前一个需要35秒钟做,和最下面的一个立即返回结果。当我查看索引时,他们似乎被设置为以相同的方式服务startCityendCity

任何人都知道他们为什么会采取不同的行为?我不知所措......

NB - 这可能会提供更深入的了解,但需要35秒一个 - 如果我按执行同样具有相同的ID直线距离,它返回结果立即以及那个时候。

不幸的是,这不是我的网站,但它可能是有用的信息。

感谢

+1

你是否看了**执行计划** SQL Server将告诉你(在管理工作室)两个查询和比较那些? – 2012-07-24 09:36:20

+1

您是否在每次测试之间执行了DBCC FREEPROCCACHE? – podiluska 2012-07-24 09:37:15

+0

嗨马克 - 谢谢 - 我不知道执行计划,那太棒了。它显示了Gulli Meel在下面描述的 - 我有一个StartHub/EndHub索引,但不是相反。非常感谢。 – 2012-07-24 09:46:39

回答

1

第二个是覆盖指数,因此快的,因为你有startcity和endcity指数。

endcity上的索引没有覆盖(因为它没有startcity),因此无论是它必须加入其他索引来获取数据或必须进行密钥查找,因此需要时间。此外,它必须做hash不同的或不同的使用SOR,而第一个犯规需要做的,以及数据在endcity排序为给定的startcity.Also为什么要使用不同的会你有startcity重复数据和endcity.If没有DUP数据删除不同。

检查然后计划这些第一个应该是索引搜索endcity + distnace索引,然后最有可能的关键查找它可以clustred索引扫描以及基于endcity的选择性。然后散列不同或排序不同。

其次应该对指数startcity + endcity只是索引查找。

你刚才提到,第二次就立即返回,这是因为数据已经在缓存中。因此,尝试以下

DBCC DROPCLEANBUFFERS DBCC FREEPROCCACHE ,然后第一次运行第二查询..

注意:PROD服务器和其他cirtical servers.Try这在一台机器上不要使用这些地方,它不会影响其他用户。

+0

嗨Gulli,是的,就是这样。索引增加了另一种方式,它像梦一样工作。非常感谢 – 2012-07-24 09:47:39

0

您只需要考虑一下......

您的表是否有主键?它是什么?这意味着什么(拥有主键)? DISTINCT关键字要求什么?

0

尝试此查询(避免DISTINCT关键字)

Select StartCityID From Distances group by StartCityID where EndCityID = 23485 

Select EndCityID From Distances group by EndCityID where StartCityID = 20045 
+0

只是奇怪什么diff截然不同和分组作用.. – 2012-07-24 09:47:11

+0

Group by适用于where子句和DISTINCT将在where子句之后应用。因此group by更好。 – AnandPhadke 2012-07-24 09:56:43

+0

Group by适用于where子句之后,而不适用于where子句之前。如果它在where子句之前应用,则意味着它将应用于整个数据集,然后数据将在稍后过滤,因此它应该比较慢,因为它会执行更多工作。 – 2012-07-24 09:59:42