为什么select count(*)选择*更快,即使表没有索引?

时间:2014-08-29 07:01:18

标签: sql sql-server-2008 tsql

对于没有主键的表和SQL Server 2008 R2中的其他索引,Select *Select count(*)所花费的时间是否存在差异?

我从一个视图中尝试过select count(*),它已经在00:05:41获取了410063922条记录。 来自视图的Select (*)对于前600000条记录已经花费了10分钟,并且查询仍在运行。所以它看起来需要1个多小时。

有没有什么方法可以让我更快地创建这个视图,而不会改变基础表的结构?

我可以为没有索引的表创建索引视图吗?

我可以在sql server中为视图使用缓存,所以如果再次调用它会花费更少的时间吗?

这是一个仅包含一个表中20列的视图。该表没有任何索引。用户可以查询该视图。我不确定用户是否确实选择了*或从视图中选择了某些条件。我唯一想做的就是建议他们进行一些更改,通过这些更改,他们对视图的查询将更快地返回结果。我正在考虑索引和缓存,但我不确定它们是否可能在没有索引的表的视图上。如其中一个答案所述,此处无法建立索引。

有人可以对sql server 2008 R2中的缓存有所了解吗?

3 个答案:

答案 0 :(得分:5)

count(*)只返回一个数字,select *返回所有数据。想象一下,必须移动所有数据以及成千上万条记录所需的时间。即使您的表可能已编入索引,在您的数十万条记录上运行select *仍然会花费大量时间,即使比以前更少,也不应该首先需要。

  

我可以为没有索引的表创建索引视图吗?

不,您必须为索引结果添​​加索引

  

我可以在sql server中为视图使用缓存,所以如果再次调用它会花费更少的时间吗?

是的,你可以,但它没有用于这样的要求。你为什么一开始就选择这么多唱片?您永远不必在任何查询中返回数百万或数千行完整数据。

修改

事实上,你试图获得没有任何where子句的数十亿行。这肯定会在任何你可以推迟的服务器上失败,所以最好停在那里:)

TL; DR

索引与SELECT * FROM myTABLE查询无关,因为没有条件和数十亿行。除非您更改查询,否则没有优化可以帮助您

答案 1 :(得分:2)

执行时间差异是由于SELEC *将显示表格的整个内容,而SELECT COUNT(*)只计算存在的行数而不显示它们。

关于优化的答案

在我看来,你是以错误的角度解决问题。首先,定义客户的实际需求非常重要,当定义需求时,您肯定能够改进视图以获得更好的性能并避免返回数十亿的数据。

有时甚至可以对表结构进行优化(我们没有关于您当前结构的任何信息)。

SQL Server将自动使用缓存系统,以便更快地执行,但这无法解决您的问题。

答案 2 :(得分:1)

当SQL Server的结果集字段列表不同时,显然可以完成许多不同的工作。我只是对连接多个表的查询进行了测试,其中有成千上万的行正在运行。我测试了不同的查询,除了SELECT子句中的字段列表之外,所有查询都相同。此外,基本查询(针对所有测试)返回零行。

SELECT COUNT(*)花了6秒,SELECT MyPrimaryKeyField花了6秒。但是,一旦我将其他任何列(甚至是小列)添加到SELECT列表中,即使没有记录返回,时间也会跳至20分钟。

当SQL Server认为需要保留其索引(例如,访问未包含在索引中的表列)时,其性能就大不相同-我们都知道这一点(这就是为什么SQL Server在创建索引时支持包括基础列的原因) )。

回到原始问题,SQL Server优化器显然在知道没有要返回的行之前选择访问索引之外的基表数据。但是,在发布者的原始方案中,没有索引或PK(不知道为什么),但也许SQL Server仍使用COUNT(*)来不同地访问表数据。