Author |
Topic |
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2012-01-20 : 11:08:20
|
Bit of an internal engine questionSay I try and get the count of rows from a huge tableSELECT COUNT(1) FROM <TheTable> Why is this not an instant operation? Assuming the Table has a clustered index (which is a balanced tree), shouldn't the CI be able to report immediately how big it is?What actually happens is a table scan and then a parallel countIs there a better way to find out how many rows a huge table has?Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
|
Kristen
Test
22859 Posts |
Posted - 2012-01-20 : 11:35:21
|
Does COUNT(*) optimise better/differently from COUNT(1)? (Sure its come up before, I can't remember the answer)SELECT Total_Rows= SUM(st.row_count)FROM sys.dm_db_partition_stats stWHERE object_name(object_id) = 'MyTable' AND (index_id < 2) but assume it is not accurate to-this-moment-in-timesp_spaceused might do? Similar inaccuracy, and presumably its using dm_db_partition_stats tooDoes NOLOCK make a difference? are there routes that avoid using SNAPSHOT (assuming you have READ_COMMITTED+_SNAPSHOT on the DB) |
 |
|
Transact Charlie
Master Smack Fu Yak Hacker
3451 Posts |
Posted - 2012-01-20 : 11:41:59
|
cheers Kristen, Thats good enough for me:quote: SELECT Total_Rows= SUM(st.row_count)FROM sys.dm_db_partition_stats stWHERE object_name(object_id) = 'MyTable' AND (index_id < 2)
Charlie===============================================================Msg 3903, Level 16, State 1, Line 1736The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION |
 |
|
GilaMonster
Master Smack Fu Yak Hacker
4507 Posts |
Posted - 2012-01-20 : 11:42:17
|
Count(*) = Count(1) in every way.It's not an instant operation because you are asking for a count of the rows that qualify for the query. That there's no filter on this particular query does not change that.For an instant count of the rows, query sys.partitions or sys.dm_db_partition_stats. Both are transactionally accurate and consistent--Gail ShawSQL Server MVP |
 |
|
Kristen
Test
22859 Posts |
Posted - 2012-01-20 : 12:07:22
|
"Both are transactionally accurate and consistent"That's well worth knowing, because from memory I had read that they were not necessarily up-to-date.I suppose I'm a bit surprised that there isn't an [internal] optimisation for COUNT(*) - but perhaps its as [or more] common to do a WHERE filter, rather than whole-table, in which case no way around actually traversing an index |
 |
|
GilaMonster
Master Smack Fu Yak Hacker
4507 Posts |
Posted - 2012-01-20 : 12:28:11
|
There is an optimisation, SQL scans the smallest index it has on the table that is valid for the count. That's why count(column) is less efficient (as well as being different logically)p.s. I should have said 'supposed to be', if those counts are wrong, it's a bug. sysindexes was known to be wrong in SQL 2000, sys.partitions is supposed to be correct.--Gail ShawSQL Server MVP |
 |
|
X002548
Not Just a Number
15586 Posts |
|
X002548
Not Just a Number
15586 Posts |
|
GilaMonster
Master Smack Fu Yak Hacker
4507 Posts |
Posted - 2012-01-20 : 14:00:28
|
No, absolutely the same.--Gail ShawSQL Server MVP |
 |
|
X002548
Not Just a Number
15586 Posts |
|
GilaMonster
Master Smack Fu Yak Hacker
4507 Posts |
Posted - 2012-01-20 : 16:43:12
|
Prior to SQL 7 if they were.--Gail ShawSQL Server MVP |
 |
|
|