Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimising select query to return the first 100 records (Adding an ORDER BY slows query)

Tags:

sql

sql-server

I am executing the following query:-

 select top 32 * from TweetEntity order by FavoriteCount desc, LastModifiedDateTime desc

This takes atleast 30seconds to execute. The table contains atleast 300,000 of records.

but when I execute the following query:

  select top 32 * from TweetEntity 

It takes less than a second to execute. I am clueless as- how to get my first query executed in less than one second. What should I be checking. Could some one point me in the correct direction.

like image 708
Venkat Avatar asked May 18 '15 05:05

Venkat


People also ask

How do you optimize orders in SQL?

From a b-tree index that you have on the table or the order of a result set in a subquery. In a slow scenario you do not have that predefined order, and MySQL has to implicitly put all data into a temporary table, sort the table on some field and return the n rows from your LIMIT clause.

How do you optimize select query timing for million records?

1:- Check Indexes. 2:- There should be indexes on all fields used in the WHERE and JOIN portions of the SQL statement 3:- Limit Size of Your Working Data Set. 4:- Only Select Fields You select as Need. 5:- Remove Unnecessary Table and index 6:- Remove OUTER JOINS.

Do joins slow down query?

Joins: If your query joins two tables in a way that substantially increases the row count of the result set, your query is likely to be slow. There's an example of this in the subqueries lesson. Aggregations: Combining multiple rows to produce a result requires more computation than simply retrieving those rows.


1 Answers

When you introduce the ORDER BY, Sql needs to evaluate the 32 highest rows based on that order, rather than any 32 rows in the table. It is apparant that there is no suitable index for Sql to use to evaluate the query.

So TL;DR you'll need to add an index on TweetEntity(FavoriteCount desc, LastModifiedDateTime desc) to improve performance, e.g.:

CREATE NONCLUSTERED INDEX IX_TweetEntity_Favourite 
ON dbo.TweetEntity(FavoriteCount desc, LastModifiedDateTime desc);

If your query is the most important / common query on the table, you can also consider changing this to be clustered index.

Edit, re Can I create as many non-clustered index as I like on a table?

Arbitrarily, you can create up to 999 non clustered indexes per table.

However, there's a catch - each index added:

  • consumes more disk space
  • and makes it slower during write operations to the table (i.e. insert new / update / delete existing rows) since indexes must also be maintained
  • if you have many similar indexes, Sql will also need to choose between the indexes when creating a query plan.

Welcome to the black art of indexing - there is no simple formula - each time you are thinking of adding a new index, you'll need to closely evaluate the benefit of each new index against existing ones. In many cases, you'll be able to tweak an existing index rather than adding new indexes each time.

like image 199
StuartLC Avatar answered Oct 03 '22 01:10

StuartLC