{"id":1008,"date":"2010-10-11T00:00:00","date_gmt":"2010-10-11T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/showplan-operator-of-the-week-sort\/"},"modified":"2021-08-16T15:02:11","modified_gmt":"2021-08-16T15:02:11","slug":"showplan-operator-of-the-week-sort","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/learn\/showplan-operator-of-the-week-sort\/","title":{"rendered":"Showplan Operator of the Week &#8211; SORT"},"content":{"rendered":"<div id=\"pretty\">\n<p class=\"start\">Over the past few weeks and months, we&#8217;ve featured the ShowPlan operators used by SQL Server to build the query plan. If you&#8217;re just getting started with my Showplan series, you can find a list of all my articles <a href=\"http:\/\/www.simple-talk.com\/author\/fabiano-amorim\/\">here<\/a>.<\/p>\n<p>Today, it is time to feature the SORT operator. The SORT operator is quite simple, and my intention with this article is to explain the use of this operator, and demonstrate how you can improve the performance of your queries by avoiding the sorting operation.<\/p>\n<p>As we can see by the name of the operator, the SORT operator sorts all rows received by the operator into order. It&#8217;s important to you keep in mind that, in some cases, the SORT operation is performed in the temporary database TempDb. Because TempDB is used for all databases within the SQL Server Instance, this can lead to TempDb becoming a bottle-neck and thereby affecting performance.<\/p>\n<p>It is surprising how often developers and DBAs take the SORT operation for granted, even though it is can be expensive in terms of CPU and I\/O. You should always pay due attention to this process, and check to make sure that it does not appear in the query plan unless it is necessary.<\/p>\n<h1>SORT into Execution Plans<\/h1>\n<p>To see the SORT in practice, let&#8217;s start with a simple query that uses the table <b>DimCustomer<\/b> from the Microsoft Sample <b>AdventureWorksDW<\/b> database.<\/p>\n<p>The following query does a simple <b>SELECT<\/b> operation, ordering the result by <b>LastName<\/b>. Because the table is not so large, the Sort will be performed in memory. That means that the data doesn&#8217;t need to be written to disk.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql\">SELECT *  &#160; FROM DimCustomer\n&#160;ORDER BY LastName\n<\/pre>\n<p>For the query above, we have the following execution plan:<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1158-FA1.jpg\" alt=\"1158-FA1.jpg\" \/><\/p>\n<p>Here we can see that the Sort is performed so as to order the data by<b> LastName<\/b>. Because I didn&#8217;t specify the word <b>ASC<\/b> or <b>DESC<\/b>, the result will be ordered ascending; which is the default option.<\/p>\n<p>SORT can also be used to remove duplicate rows, in other words, perform a <b>DISTINCT <\/b>operation. For instance, consider the following query.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql\">SELECT DISTINCT AddressLine1  &#160; FROM DimCustomer\n<\/pre>\n<p>From this, we have the following execution plan:<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1158-FA2.jpg\" alt=\"1158-FA2.jpg\" \/><\/p>\n<p>Here the SORT is a &#8220;Distinct SORT&#8221;. You&#8217;ll notice that I didn&#8217;t specify anything in an <b>ORDER BY<\/b> clause; I&#8217;m just getting a distinct list of <b>AddessLine1<\/b>.<\/p>\n<h1>SORT in Memory\/Disk<\/h1>\n<p>It&#8217;s important to know that the SORT operation is a very expensive task, and it usually requires a lot of memory. When the query plan is created, SQL Server reserves the memory to perform the SORT in a &#8216;grant&#8217;; but sometimes this sort is written to disk to run in the <b>TempDb<\/b> database. To understand more about SQL Server memory grant, look at <a href=\"http:\/\/blogs.msdn.com\/b\/sqlqueryprocessing\/archive\/2010\/02\/16\/understanding-sql-server-memory-grant.aspx\">this article<\/a>.<\/p>\n<p>To see when the SORT operation is being done in <b>TempDb<\/b>, we can use the SQL Server Profiler to capture an event called &#8216;Sort Warnings&#8217;.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1158-FA3.jpg\" alt=\"1158-FA3.jpg\" \/><\/p>\n<p class=\"pullout\">* <strong>Update: <\/strong>Just adding more memory is not the only option, and maybe not the easiest. If you want to know more about the sort warning you should read the comments below in this article. Thanks a lot to Holger, Chris and Celko for all comments. F.A.<\/p>\n<p>Many of these warnings are an indication that you need more memory*. If your application requires the use of many disk-based SORT operations, you can also check physical location of the <b>TempDb<\/b> database so as to be sure that it is using the best storage subsystem available.<\/p>\n<h1>How to Avoid SORT operations<\/h1>\n<p>The easiest way to avoid a SORT is by creating an Index. As we know, indexes are ordered by the columns so that , if you create an index covering your query, the Query Optimizer identifies this index and uses it to avoid a SORT operation. Let&#8217;s look at a sample using the same query used before.<\/p>\n<p>The following command creates an index using the column <b>LastName<\/b>.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql\">CREATE INDEX ix ON DimCustomer(LastName)<\/pre>\n<p>Now, let&#8217;s see the execution plan of the same query that we&#8217;ve already used.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql\">SELECT *  &#160; FROM DimCustomer\n&#160;ORDER BY LastName\n<\/pre>\n<p>For this query, we have the following execution plan:<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1158-FA4.jpg\" alt=\"1158-FA4.jpg\" \/><\/p>\n<p>This time, the Query Optimizer has chosen to read the data from the <b>ix<\/b> index and then uses a <a href=\"http:\/\/www.simple-talk.com\/sql\/learn-sql-server\/showplan-operator-of-the-week---bookmarkkey-lookup\/\">Key Lookup<\/a> to read the other columns to the clustered index. The query optimizer is smart enough to understand that the index is ordered by the column <strong>LastName<\/strong> and there is no reason to order the data again.<\/p>\n<p>Another very common usage of a sorting operation is when developers create reports with a lot of options to allow the end-users to choose how to sort the result. In this case, the <b>ORDER BY<\/b> clause can often be avoided in your query. It is usually better to sort the data within the client application, not the server.<\/p>\n<p>SQL Server also can use the SORT operator for other operations, for instance to be able to use the Merge algorithm, aAnd you can also avoid this by creating the proper index.<\/p>\n<p>That&#8217;s all folks, I hope you&#8217;ve enjoyed learning about SORT operator, and I&#8217;ll see you <b><i>soon<\/i><\/b> with more &#8220;Showplan Operators&#8221;.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Fabiano introduces another ShowPlan operator that is used to build a query plan, or perform an operation specified in the DML. Once again, Fabiano demonstrates why it is important to be aware of these operators when getting queries to perform well.&hellip;<\/p>\n","protected":false},"author":65554,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143525],"tags":[4178,5177,4149,5286,5162,5287,4150],"coauthors":[],"class_list":["post-1008","post","type-post","status-publish","format-standard","hentry","category-learn","tag-bi","tag-fabiano-amorim","tag-learn-sql-server","tag-operator-of-the-week","tag-showplan","tag-sort","tag-sql"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1008","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/65554"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=1008"}],"version-history":[{"count":4,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1008\/revisions"}],"predecessor-version":[{"id":92142,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1008\/revisions\/92142"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=1008"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=1008"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=1008"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=1008"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}