我想了解sql count究竟是如何工作的。是整个表扫描发生还是读取表的某些属性。但是我觉得如果有大量记录的大表,表扫描将是一个开销。
答案 0 :(得分:12)
通常,执行表扫描或索引扫描。这主要是因为在支持MVCC的引擎中,不同的事务可能会看到不同的行,因此没有单个“行计数”同时适用于所有人。
同样,如果你有一个WHERE子句,那么不同客户端的where条件可能不同,所以他们看到不同的数字。
如果需要对大表进行大量计数,请考虑将自己的计数器存储在不同的表中。具体如何执行此操作完全取决于应用程序。
答案 1 :(得分:6)
这在很大程度上取决于您使用的是哪种SQL实现(MS SQL Server,MySQL,Oracle,PostgreSQL等),以及它的优化程序是多么聪明。
它也可能取决于查询。例如,像
这样的东西SELECT COUNT(primary_key) FROM table;
优化器可能会意识到不需要扫描表(因为没有使用WHERE
进行过滤,并且任何值都不可能为NULL)并且只返回表的大小。使用更复杂的查询(存在过滤或NULL的可能性),数据库可能必须扫描表,或者可以使用索引进行一些优化。
答案 2 :(得分:3)
这显然取决于实现(即不同的RDBMS可能采用不同的策略),并且依赖于使用(即select count(*) from mytable
和select count(*) from mytable where myfield < somevalue
)即使在同一个DB中也可能使用不同的方法。
如果您尝试根据索引已经表达的某些分区来获取计数,智能数据库将尝试单独使用索引。或者像Foxbase中使用的旧“rushmore”。
所以,“它取决于”,但在一天结束时,如果没有更好的方法可用,是的,数据库将执行表扫描。
答案 3 :(得分:2)
通常是某种索引扫描,除非表上没有唯一索引。
奇怪的是,大多数数据库引擎只能通过扫描来计算。他们甚至提供了使用表元数据计数的替代解决方案例如,SQL Server支持SELECT rowcnt FROM sysindexes ...
。但是,这些通常不是100%准确。
答案 4 :(得分:1)
使用计数功能进行表扫描,而不是使用表上的计数来获取可以使用的行总数:
SELECT
Total_Rows= SUM(st.row_count)
FROM
sys.dm_db_partition_stats st
WHERE
object_name(object_id) = 'TABLENAME'
或
SELECT sysobjects.[name], max(sysindexes.[rows]) AS TableRows
FROM sysindexes INNER JOIN sysobjects ON sysindexes.[id] = sysobjects.[id]
WHERE sysobjects.xtype = 'U' and sysobjects.[name]='tablename'
GROUP BY sysobjects.[name]
ORDER BY max(rows) DESC
获得总计数的其他方式:http://www.codeproject.com/Tips/58796/Number-of-different-way-to-get-total-no-of-row-fro.aspx
答案 5 :(得分:1)
这取决于使用的DBMS。
如果存在索引,则每个表行应该有一个索引行。智能DBMS可能会选择最小的索引并计算索引行。
最后,如果表足够小,它可能会计算表行并绕过索引。
答案 6 :(得分:0)
在postgreSQL中执行表扫描。 我认为这取决于实现。
编辑: 见this link
答案 7 :(得分:-1)
真的没关系!
我假设你想要某种分页的行计数...所以只需确保你的分页算法符合最佳实践并忘记引擎的工作方式。
让数据库业务人员关心这一点,只需遵循您正在使用的数据库专家的建议。
SQL Server - http://www.4guysfromrolla.com/webtech/042606-1.shtml
Oracle - Paging with Oracle
MySQL - http://php.about.com/od/phpwithmysql/ss/php_pagination.htm