2011-05-25 141 views
1

我有一个表中的多个记录看起来像这样的:性能问题

 COLUMN1  | NUMBER 
-------------------------------------- 
'http://namespace1/#1'|  1 
'http://namespace1/#2'|  0 
'http://namespace1/#3'|  0 
'http://namespace1/#4'|  0 
'http://namespace2/#1'|  0 
'http://namespace2/#2'|  0 
'http://namespace2/#3'|  0 
'http://namespace2/#4'|  1 
... 

现在,我的查询看起来是这样的:

SELECT COLUMN1 FROM MyTable WHERE NUMBER = 1 AND COLUMN1 LIKE 'http://namespace1/%' 

问题这个查询就是这样,当表中有很多记录时,它非常慢。只能返回一条记录。

查询有更快的选择吗?

+3

你有'COLUMN1'上的索引,不是吗?另外,你的价值观有多独特? %数据以'http:// namespace1'开始? – GSerg 2011-05-25 15:17:33

+0

@GSerg是column1已编入索引 – 2011-05-25 15:19:29

+2

您是否检查过查询的查询计划? – 2011-05-25 15:19:50

回答

1

由于只能返回一条记录,因此可以执行top(1)。在某些情况下,top(1)会在第一次比赛时停止条件循环(当没有order by时)。查询将会更快。

SELECT top(1) COLUMN1 FROM MyTable WHERE NUMBER = 1 AND COLUMN1 LIKE 'http://namespace1/%' 
+0

这是基于样本数据的一条记录的假设。但是,这仍然是错误的。 TOP在JOIN和WHERE之后应用。请参阅http://msdn.microsoft.com/en-us/library/ms189499.aspx。这意味着查询不会停止,直到它具有与WHERE条件匹配的所有行。 – gbn 2011-05-25 19:51:07

+0

您将不得不向我解释为什么没有top(1)(query1)和查询(query2)的查询在性能上有如此巨大的差异。这两个查询返回的数据量相同,但query2速度更快(查询1为900毫秒,查询2为小于50毫秒)。 – 2011-05-25 20:06:37

+0

我没有看到它是你的问题。可能是因为NUMBER = 1时只有一行,因此它对齐(基于统计数据)。或者它删除潜在的密钥查找(由于没有发布查询计划,因此无法查看)。我*不会依赖于这个:像这样的TOP会让事情变得更糟。当我(和另外两个人)提出建议时,你是否在这两列创建了索引?如果没有,请尝试没有TOP。如果你有,发生了什么事? – gbn 2011-05-25 20:14:54

2

因为WHERE子句有2个条件,所以您需要在NUMBER和COLUMN1列上使用索引。

当前的COLUMN1索引由于NUMBER = 1位而被忽略,或者它与键查找一起使用以获得NUMBER。无论哪种方式,这解释了OP所看到的。

编辑:

无论指数(NUMBER,COLUMN1)(COLUMN1,NUMBER)是试验和错误。 我怀疑第二个如果只有2号值,但情况因人而异

+0

+1两列索引击败我...... – takrl 2011-05-25 15:23:02

+0

索引如何帮助您在列上使用像运算符时的帮助? – Deepesh 2011-05-25 15:23:56

+2

@ user751975:它仍然可以在索引中进行词干搜索,只用尾随通配符。当您查看“gb%”的(实际)图书索引时,您需要先扫描g..b,然后再扫描“gb”范围。另一种方式:'gb%'与'>'gb'相同并且<'gc'' – gbn 2011-05-25 15:28:26

0

一个covering indexCOLUMN1NUMBER,无论是聚集或非聚集,可能是最好的选择。

1

在column1和number列上添加索引。尝试两种方式,column1和number/number和column1。一次尝试一个索引。根据数据可能会有所不同。

索引有助于类似的命令,其中%不在类似值的前面。在这种情况下,它应该有很大的帮助。