在SQL中添加Where子句花费的时间更少-为什么?

在SQL中添加Where子句花费的时间更少-为什么?,sql,where-clause,query-analyzer,Sql,Where Clause,Query Analyzer,执行所需时间超过: select count(*) from table 使用where子句,SQL必须做一些额外的工作,以了解为什么具有where子句的查询速度很快。通过传递where子句,您可以指示RDBMS只需扫描表的一部分即可找到结果。如果没有WHERE子句,则需要扫描所有表。这并不意味着一种解决方案总是比另一种更快 一种解决方案是否比另一种更快实际上取决于多个因素,例如: 表结构(例如,WHERE子句中的列上是否有索引) 大小(行数) 过滤列中的数据分布 统计数据的准确性(是最

执行所需时间超过:

select count(*) 
from table 

使用
where
子句,SQL必须做一些额外的工作,以了解为什么具有where子句的查询速度很快。

通过传递where子句,您可以指示RDBMS只需扫描表的一部分即可找到结果。如果没有WHERE子句,则需要扫描所有表。这并不意味着一种解决方案总是比另一种更快

一种解决方案是否比另一种更快实际上取决于多个因素,例如:

  • 表结构(例如,WHERE子句中的列上是否有索引)

  • 大小(行数)

  • 过滤列中的数据分布

  • 统计数据的准确性(是最近为该表计算的统计数据,样本量,…)


基于这些因素,RDBMS的优化器将决定应该使用哪个执行计划,这将最终决定查询性能。

这通常是因为您有一个包含列
x
的索引

通常,
count(*)
需要扫描所有行或扫描最小索引(取决于数据库)

相比之下,对于
where
子句,基本上有两种方法:

  • 扫描所有行并执行比较
  • 在索引中查找满足条件的值
第二种方法通常比第一种方法快得多


其他因素也可能起作用。例如,另一个过程可能是更新或插入行,这会对表或表的某些部分设置锁。这会减慢其他查询的速度。不过,原因很可能是存在索引。

SQL引擎不必扫描整个表来计算行数,例如,它可以使用索引/统计信息。您应该为这两个查询提供完整的表结构和执行计划。第二,一旦将数据加载到缓冲区缓存,它就不再从磁盘读取。您是否在清除缓存的情况下多次运行测试?包含索引的表定义是什么?执行计划是什么样子的?多次执行的确切时间是多少?这里where子句中的x不是索引,因此,查询将扫描所有行,并将做一些额外的工作,对吗?@jayantsigh可能会将谓词推送到扫描中,并减少消除它的工作,然后将所有行传递到一个聚合中,但您尚未提供足够的信息,以了解这是否是一个合理的解释。
select count(*) 
from table 
where x = '1' 
here x is not an index