Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are a few issues with this query (and this apply to every query).</p> <h1>Lack of index</h1> <p>Lack of index on <code>er101_upd_date_iso</code> column is most important thing as <a href="https://stackoverflow.com/users/1583/oded">Oded</a> has already mentioned.</p> <p>Without matching index (which lack of could cause table scan) there is no chance to run fast queries on big tables.</p> <p>If you cannot add indexes (for various reasons including <em>there is no point in creating index for just one ad-hoc query</em>) I would suggest a few workarounds (which can be used for ad-hoc queries):</p> <h2>1. Use temporary tables</h2> <p>Create temporary table on subset (rows and columns) of data you are interested in. Temporary table should be much smaller that original source table, can be indexed easily (if needed) and can <em>cached</em> subset of data which you are interested in.</p> <p>To create temporary table you can use code (not tested) like:</p> <pre><code>-- copy records from last month to temporary table INSERT INTO #my_temporary_table SELECT * FROM er101_acct_order_dtl WITH (NOLOCK) WHERE er101_upd_date_iso &gt; DATEADD(month, -1, GETDATE()) -- you can add any index you need on temp table CREATE INDEX idx_er101_upd_date_iso ON #my_temporary_table(er101_upd_date_iso) -- run other queries on temporary table (which can be indexed) SELECT TOP 100 * FROM #my_temporary_table ORDER BY er101_upd_date_iso DESC </code></pre> <p>Pros:</p> <ul> <li>Easy to do for any subset of data.</li> <li>Easy to manage -- it's <em>temporary</em> and it's <em>table</em>.</li> <li>Doesn't affect overall system performance like <code>view</code>.</li> <li>Temporary table can be indexed.</li> <li>You don't have to care about it -- it's temporary :).</li> </ul> <p>Cons:</p> <ul> <li>It's snapshot of data -- but probably this is good enough for most ad-hoc queries.</li> </ul> <h2>2. Common table expression -- CTE</h2> <p>Personally I use <a href="http://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx" rel="noreferrer">CTE</a> a lot with ad-hoc queries -- it's help a lot with building (and testing) a query piece by piece.</p> <p>See example below (the query starting with <code>WITH</code>).</p> <p>Pros:</p> <ul> <li>Easy to build starting from <em>big view</em> and then selecting and filtering what really you need.</li> <li>Easy to test.</li> </ul> <p>Cons:</p> <ul> <li>Some people dislike CDE -- CDE queries seem to be long and difficult to understand.</li> </ul> <h2>3. Create views</h2> <p>Similar to above, but create views instead of temporary tables (if you play often with the same queries and you have MS SQL version which supports indexed views.</p> <p>You can create views or <a href="http://msdn.microsoft.com/en-us/library/dd171921(v=SQL.100).aspx" rel="noreferrer">indexed views</a> on subset of data you are interested in and run queries on view -- which should contain only interesting subset of data much smaller than the whole table.</p> <p>Pros:</p> <ul> <li>Easy to do.</li> <li>It's up to date with source data.</li> </ul> <p>Cons:</p> <ul> <li>Possible only for defined subset of data.</li> <li>Could be inefficient for large tables with high rate of updates.</li> <li>Not so easy to manage.</li> <li>Can affect overall system performance.</li> <li>I am not sure indexed views are available in every version of MS SQL.</li> </ul> <h1>Selecting all columns</h1> <p>Running <em>star query</em> (<code>SELECT * FROM</code>) on big table is not good thing...</p> <p>If you have large columns (like long strings) it takes a lot of time to read them from disk and pass by network.</p> <p>I would try to replace <code>*</code> with column names which you really need.</p> <p>Or, if you need all columns try to rewrite query to something like (using <em>common data expression</em>):</p> <pre><code>;WITH recs AS ( SELECT TOP 100 id as rec_id -- select primary key only FROM er101_acct_order_dtl ORDER BY er101_upd_date_iso DESC ) SELECT er101_acct_order_dtl.* FROM recs JOIN er101_acct_order_dtl ON er101_acct_order_dtl.id = recs.rec_id ORDER BY er101_upd_date_iso DESC </code></pre> <h1>Dirty reads</h1> <p>Last thing which could speed up the ad-hoc query is allowing <em>dirty reads</em> with <a href="http://msdn.microsoft.com/en-us/library/ms187373.aspx" rel="noreferrer">table hint <code>WITH (NOLOCK)</code></a>.</p> <p>Instead of hint you can <a href="http://msdn.microsoft.com/en-us/library/ms173763.aspx" rel="noreferrer">set transaction isolation level</a> to read uncommited:</p> <pre><code>SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED </code></pre> <p>or set proper SQL Management Studio setting.</p> <p>I assume for ad-hoc queries <em>dirty reads</em> is good enough.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload