Mikael Eriksson tem uma boa explicação abaixo porque a primeira consulta é rápida:
SQL Server otimize-o em:
if exists(select * from BookChapters)
. Então, ele procura a presença de uma linha em vez de contar todas as linhas da tabela. Para as outras duas consultas, o SQL Server usaria a seguinte regra. Para realizar uma consulta como
SELECT COUNT(*)
, o SQL Server usará o não clusterizado mais estreito index para contar as linhas. Se a tabela não tiver nenhum índice não clusterizado, ela terá que varrer a tabela. Além disso, se sua tabela tiver um clustered index você pode obter sua contagem ainda mais rápido usando a seguinte consulta (emprestada deste site Get Row Counts Fast!)
--SQL Server 2005/2008
SELECT OBJECT_NAME(i.id) [Table_Name], i.rowcnt [Row_Count]
FROM sys.sysindexes i WITH (NOLOCK)
WHERE i.indid in (0,1)
ORDER BY i.rowcnt desc
--SQL Server 2000
SELECT OBJECT_NAME(i.id) [Table_Name], i.rows [Row_Count]
FROM sysindexes i (NOLOCK)
WHERE i.indid in (0,1)
ORDER BY i.rows desc
Ele usa a tabela de sistema sysindexes. Mais informações você pode encontrar aqui SQL Server 2000, SQL Server 2005, SQL Server 2008, SQL Server 2012
Aqui está outro link Por que meu SELECT COUNT(*) está tão lento? com outra solução. Ele mostra a técnica que a Microsoft usa para exibir rapidamente o número de linhas quando você clica com o botão direito do mouse na tabela e seleciona propriedades.
select sum (spart.rows)
from sys.partitions spart
where spart.object_id = object_id(’YourTable’)
and spart.index_id < 2
Você deve descobrir que isso retorna muito rapidamente, não importa quantas tabelas você tenha.
Se você ainda estiver usando o SQL 2000, poderá usar a tabela sysindexes para obter o número.
select max(ROWS)
from sysindexes
where id = object_id(’YourTable’)
Esse número pode estar um pouco diferente dependendo da frequência com que o SQL atualiza a tabela sysindexes, mas geralmente está correto (ou pelo menos próximo o suficiente).