What is "include only" option on the mssql index creation tab? - sql-server

There is a "Include Only" option in each row (which is actually a table column) in the index.
What is it and is it needed for?
http://pasteboard.s3.amazonaws.com/images/1350293092227927.png
(SQL Manager lite for SQL Server)

Include only will make it an "included column". Included columns are only included at the leaf level of the index rather than in every level of the b-tree. This gets around max size/no of columns in the key and allows you to more easily cover queries
The way you would normally use included columns is as follows:
When creating an index to support a query, add the columns included in WHERE, JOIN and aggregate functions, etc to the index key. Columns that only appear in the SELECT list, add as Included Columns. This means that SQL Server will be able to seek the index but then obtain the remaining columns from the bottom of the index, without having to jump to the Heap or Clustered Index to obtain the columns.

Related

Optimizing a table for the latest/last rows in Azure SQL Server

I have a table on a MS Azure SQL DB with 60,000 rows that is starting to take longer to execute with a SELECT statement. The first column is the "ID" column which is the primary key. As of right now, there is no other indexes. The thing about this table is the rows are based on recent news articles, therefore the last rows in the table are always going to be accessed more than the older rows.
If possible, how can I tell SQL Server to start querying at the end of the table working backwards when I do a SELECT operation?
Also, what can I do with indexes to make reading from the table faster with the last rows as the priority?
Typically, the SQL Server query optimizer will choose the data access strategy based on the available indexes, data distribution statistics & query. For example, SQL Server can scan an index forward, backward, physical order & so on. The choice is determined based on many variables.
In your example, if there is a date/time column in the table then you can index and use that in your predicate(s). This will automatically enable use of that index if that is the most selective one.
Alternatively, you can partition the table based on a column and access most recent data based on the partitioning key. This is common use of partitioning with a rolling window. With this approach, the predicate in your queries will specify the partitioning column which will help the optimizer pick the correct set of partitions to scan. This will dramatically reduce the amount of data that needs to be searched since partition elimination happens before execution depending on the query plan.

What happens to a clustered index when PK is created on two columns in SQL Server

I just created a table with TWO primary keys in SQL Server. One column is age, another is ID number and I set the option to CLUSTER INDEX, so it automatically creates a cluster index on both columns. However, when I query the table, the results only seem to sort the ID and completely disregard/ignore the AGE (other PK and other Cluster index column). Why is this? Why is it only sorting based on the first cluster index column?
The query optimizer may decide to use the physical ordering of the rows in the table if there is no advantage in ordering any other way. So, when you select from the table using a simple query, it may be ordered this way. It is very easy to assume that the rows are physically stored in the order specified within the definition of your clustered index. But this turns out to be a false assumption.
Please view the following article for more details: Clustered Index do “NOT” guarantee Physically Ordering or Sorting of Rows

Composite and Covering index

What is the diffrence between composite index and covering index in Sql Server ?
A covering index is a composite index that contains every column you are currently retrieving with your select statement and that participates in the where clause. It is one of the best ways to improve query performance substantially.
A covering index is a composite index that covers (hence the name) all columns that are necessary to fulfill a query or a join condition.
There is nothing special about SQL server here, these are generic designations.
A composite index is also a covering index when the index contains your search criteria and all the data your query is attempting to retrieve. In this example:
SELECT a,b,c FROM Foo WHERE a = 'FooFoo'
A covering index would contain column a (your search predicate) as well as the columns b and c.
In this case SQL Server is optimized to return those values found in the index and does not need to make an additional look up in the actual table. If b and c are frequently returned but rarely searched on then the index might be set up such that b and c are included in the index but not indexed.
Before SQL Server 2005 DBA's would add additional 'covering' columns to their indexes to achieve this optimization. In SQL Server 2005 an additional feature was added that allowed you to include covering columns in the leaf nodes of the index that were not part of the index tree. When creating an index you can specify additional 'covering' columns in the include clause. These columns will not be indexed but added to the leaf node of the index saving SQL Server from looking up the additional data in the main table. Adding the data to the include clause saves SQL Server the overhead of adding the additional data to the search tree while gaining the optimization that a covering index brings.

What is a Bookmark Lookup in Sql Server?

I'm in the process of trying to optimize a query that looks up historical data. I'm using the query analyzer to lookup the Execution Plan and have found that the majority of my query cost is on something called a "Bookmark Lookup". I've never seen this node in an execution plan before and don't know what it means.
Is this a good thing or a bad thing in a query?
A bookmark lookup is the process of finding the actual data in the SQL table, based on an entry found in a non-clustered index.
When you search for a value in a non-clustered index, and your query needs more fields than are part of the index leaf node (all the index fields, plus any possible INCLUDE columns), then SQL Server needs to go retrieve the actual data page(s) - that's what's called a bookmark lookup.
In some cases, that's really the only way to go - only if your query would require just one more field (not a whole bunch of 'em), it might be a good idea to INCLUDE that field in the non-clustered index. In that case, the leaf-level node of the non-clustered index would contain all fields needed to satisfy your query (a "covering" index), and thus a bookmark lookup wouldn't be necessary anymore.
Marc
It's a NESTED LOOP which joins a non-clustered index with the table itself on a row pointer.
Happens for the queries like this:
SELECT col1
FROM table
WHERE col2 BETWEEN 1 AND 10
, if you have an index on col2.
The index on col2 contains pointers to the indexed rows.
So, in order to retrieve the value of col1, the engine needs to scan the index on col2 for the key values from 1 to 10, and for each index leaf, refer to the table itself using the pointer contained in the leaf, to find out the value of col1.
This article points out that a Bookmark Lookup is SQL Server 2000's term, which is replaced by NESTED LOOP's between the index and the table in SQL Server 2005 and above
From MSDN regarding Bookmark Lookups:
The Bookmark Lookup operator uses a
bookmark (row ID or clustering key) to
look up the corresponding row in the
table or clustered index. The Argument
column contains the bookmark label
used to look up the row in the table
or clustered index. The Argument
column also contains the name of the
table or clustered index in which the
row is looked up. If the WITH PREFETCH
clause appears in the Argument column,
the query processor has determined
that it is optimal to use asynchronous
prefetching (read-ahead) when looking
up bookmarks in the table or clustered
index.

Index Seek with Bookmark Lookup Only Option for SQL Query?

I am working on optimizing a SQL query that goes against a very wide table in a legacy system. I am not able to narrow the table at this point for various reasons.
My query is running slowly because it does an Index Seek on an Index I've created, and then uses a Bookmark Lookup to find the additional columns it needs that do not exist in the Index. The bookmark lookup takes 42% of the query time (according to the query optimizer).
The table has 38 columns, some of which are nvarchars, so I cannot make a covering index that includes all the columns. I have tried to take advantage of index intersection by creating indexes that cover all the columns, however those "covering" indexes are not picked up by the execution plan and are not used.
Also, since 28 of the 38 columns are pulled out via this query, I'd have 28/38 of the columns in the table stored in these covering indexes, so I'm not sure how much this would help.
Do you think a Bookmark Lookup is as good as it is going to get, or what would another option be?
(I should specify that this is SQL Server 2000)
OH,
the covering index with include should work. Another option might be to create a clustered indexed view containing only the columns you need.
Regards,
Lieven
You could create an index with included columns as another option
example from BOL, this is for 2005 and up
CREATE NONCLUSTERED INDEX IX_Address_PostalCode
ON Person.Address (PostalCode)
INCLUDE (AddressLine1, AddressLine2, City, StateProvinceID);
To answer this part "I have tried to take advantage of index intersection by creating indexes that cover all the columns, however those "covering" indexes are not picked up by the execution plan and are not used."
An index can only be used when the query is created in a way that it is sargable, in other words if you use function on the left side of the operator or leave out the first column of the index in your WHERE clause then the index won't be used. If the selectivity of the index is low then also the index won't be used
Check out SQL Server covering indexes for some more info

Resources