Deepak Mishra
Deepak Mishra

Reputation: 3183

Why select count(*) is faster the select * even if table has no indexes?

Is there any diffrence between the time taken for Select * and Select count(*) for the table having no primary key and other indexes in SQL server 2008 R2?

I have tried select count(*) from a view and it has taken 00:05:41 for 410063922 records. Select (*) from view has already taken 10 minutes for first 600000 records and the query is still running. So it looks like that it will take more than 1 hour.

Is there any way through which I can make this view faster without any change in the structure of the underlying tables?

Can I create indexed view for tables without indexes?

Can I use caching for the view inside sql server so if it is called again, it takes less time?

It's a view which contains 20 columns from one table only. The table does not have any indexes.The user is able to query the view. I am not sure whether user does select * or select somecolumn from view with some where conditions. The only thing which I want to do is to propose them for some changes through which their querying on the view will return results faster. I am thinking of indexing and caching but I am not sure whether they are possible on a view with table having no indexes. Indexing is not possible here as mentioned in one of the answers.

Can anyone put some light on caching within sql server 2008 R2?

Upvotes: 1

Views: 2320

Answers (3)

Marco P
Marco P

Reputation: 11

SQL Server apparently does very different work when its result set field list is different. I just did a test of a query joining several tables where many millions of rows were in play. I tested different queries, which were all the same except for the list of fields in the SELECT clause. Also, the base query (for all tests) returned zero rows.

The SELECT COUNT(*) took 6 seconds and the SELECT MyPrimaryKeyField took 6 seconds. But once I added any other column (even small ones) to the SELECT list, the time jumped to 20 minutes - even though there were no records to return.

When SQL Server thinks it needs to leave its indexes (e.g., to access table columns not included in an index) then its performance is very different - we all know this (which is why SQL Server supports including base columns when creating indexes).

Getting back to the original question, the SQL Server optimizer apparently chooses to access the base table data outside of the indexes before it knows that it has no rows to return. In the poster's original scenario, though, there were no indexes or PK (don't know why), but maybe SQL Server is still accessing table data differently with COUNT(*).

Upvotes: 1

Joël Salamin
Joël Salamin

Reputation: 3576

The execution time difference is due to the fact that SELEC * will show the entire content of your table and the SELECT COUNT(*) will only count how many rows are present without showing them.

Answer about optimisation

In my opinion you're taking the problem with the wrong angle. First of all it's important to define the real need of your clients, when the requirements are defined you'll certainly be able to improve your view in order to get better performance and avoid returning billions of data.

Optimisations can even be made on the table structure sometimes (we don't have any info about your current structure).

SQL Server will automatically use a system of caching in order to make the execution quicker but that will not solve your problem.

Upvotes: 2

Hanky Panky
Hanky Panky

Reputation: 46900

count(*) returns just a number and select * returns all the data. Imagine having to move all that data and the time it takes for your hundred of thousands of records. Even if your table was indexed probably, running select * on your hundreds of thousands of records will still take a lot of time even if less than before, and should never bee needed in the first place.

Can I create indexed view for tables without indexes?

No, you have to add indexes for indexed results

Can I use caching for the view inside sql server so if it is called again, it takes less time?

Yes you can, but its of no use for such a requirement. Why are you selecting so many records in the first place? You should never have to return millions or thousands of rows of complete data in any query.

Edit

Infact you are trying to get billions of rows without any where clause. This is bound to fail on any server that you can get hold off, so better stop there :)

TL;DR

Indexes do not matter for a SELECT * FROM myTABLE query because there is no condition and billions of rows. Unless you change your query, no optimization can help you

Upvotes: 5

Related Questions