Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimize query so it does not need a Top N sort

I have the following query

select top 25
    tblSystem.systemName,
    tblCompany.name
from 
    tblSystem
    join tblCompany
        on tblSystem.fkCompanyID = tblCompany.pkCompanyID
order by
    tblSystem.systemName, 
    tblCompany.name

That generates the first execution plan in the picture, the 2nd is the same query without the order by

enter image description here
Is there any way a can get rid of the TOP N Sort (so only a TOP is needed) by indexing the tables in a particular way?

like image 770
Magnus Avatar asked Nov 14 '13 16:11

Magnus


People also ask

How do I stop sorting in SQL Server?

An ordered index scan scales linearly. An actual sort scans in an extra-linear fashion--more specifically, in an n log n fashion. Therefore, especially when dealing with a very large number of rows, it's good to be able to avoid explicit sorting by pulling the data preordered from an index.

Does indexing improve sorting?

Using the indexes can improve the performance of the sorting operation because the indexes create an ordered structure of the table rows so that the storage engine can fetch the table rows in a pre-ordered manner using the index structure.

How does ORDER BY affect query performance?

Anytime you add ordering to a query it will affect performance because the results have to be ordered. The amount of impact however is NOT a static answer. There a number of factors involved.


1 Answers

Add an index to tblSystem on systemName with fkCompanyID included.

create index IX_tblSystem_systemName 
  on tblSystem(systemName) include(fkCompanyID)

Rewrite your query to pick the 25 first values (with ties) from tblSystem in a derived table ordered by systemName and then join to tblCompany to get the 25 values you need.

Depending on if fkCompanyID allows null values or not you need to filter out null values in the where clause in the derived table.

select top (25)
  S.systemName,
  C.name 
from (
     select top (25) with ties
       S.fkCompanyID,
       S.systemName
     from tblSystem as S
     where S.fkCompanyID is not null
     order by S.systemName
     ) as S
  inner join tblCompany as C
    on S.fkCompanyID = C.pkCompanyID
order by S.systemName,
         C.name

You will still have to top(n) sort operator but it will only sort the 25 rows (+ ties) that you got from the derived table joined against tblCompany.

enter image description here

like image 145
Mikael Eriksson Avatar answered Dec 08 '22 10:12

Mikael Eriksson