What is the difference between composite non clustered index and covering index - sql-server

SQL Server 2005 includes "covering index" feature which allows us to select more than one non key column to be included to the existing non clustered index.
For example, I have the following columns:
EmployeeID, DepartmentID, DesignationID, BranchID
Here are two scenarios:
EmployeeID is a primary key with
clustered index and the remaining
columns (DepartmentID, DesignationID,
BranchID) are taken as non clustered
index (composite index).
EmployeeID is a primary key with
clustered index and DepartmentID is
non clustered index with
DesignationID, BranchID are "included
columns" for non clustered index.
What is the difference between the above two? If both are same what's new to introduce "Covering Index" concept?

The difference is that if there are two rows with the same DepartmentID in the first index they will be sorted based on their values of DesignationID and BranchID. In the second case they will not be sorted relative to each other and could appear in any order in the index.
In terms of what this means to your application:
A query which can use an index on (DepartmentID, DesignationID) can be more efficient with the first query than the second.
Building the first index may take slightly longer because of the extra sorting required.

Covered index is a nonclustered index with INCLUDE clause

Related

Non clustered indexes for special case

TABLE SellerTransactions
string SellerId,
string ProductId,
DateTime CreateDate,
string BankNumber,
string Name(name+' '+surname+' 'alias),
string Comments,
decimal Amount
etc...
what would be the best case scenario for search/filtering with non clustered index when we search by sellerID, ProductIds, CreateDate and sometimes Amount/ BankNumber.. should the non clustered index be only on (first sellerID, ProductIds, CreateDate) columns or on all possible columns where the search might happen (a single big non clustered index).
Query will always contain (sellerID, ProductIds, CreateDate) and sometimes additionally bankNumber/Amount.
Say 90% of the time sellerID, ProductIds, CreateDate will be searched and 10% of the time sellerID, ProductIds, CreateDate & Amount or bankNumber.
I was thinking having a nonclustered index on (sellerID, ProductIds, CreateDate) and separate ones for amount and bank number.
I think you have to use a filtered index to improve the performance of your query.
What is a filtered index?
Filtered index is used to get some portion of table.
i.e. a filtered index applies a filter on index which improves query performance.
For more info, see: https://learn.microsoft.com/en-us/sql/relational-databases/indexes/create-filtered-indexes?view=sql-server-2017
Syntax
CREATE NONCLUSTERED INDEX Non_ClustredIndexName
ON Table(ColumnName)
WHERE ColumnName = #ColumnValue
Example as per your table:
1.
CREATE NONCLUSTERED INDEX FI_Employee_DOJ
ON tbl_SellerTransactions(ST_Name)
WHERE ST_Name IS NOT NULL
2.
CREATE NONCLUSTERED INDEX NonCluster_sellerID
ON tbl_SellerTransactions(sellerID)
WHERE sellerID BETWEEN '100' AND '500'
3.
CREATE NONCLUSTERED INDEX FI_Employee_DOJ
ON tbl_SellerTransactions(ST_Name)
INCLUDE(SellerId,amt,ProductId,BankNumber) --Including remaining columns in the index
WHERE ST_Name IS NOT NULL
Notice
Filtered index can be used on views only if filtered indexes are persisted views
Filtered indexes are not created fulltext indexes

Multiple Clustered Indexes on a Single Table?

I thought we could only place one clustered index on one table, and put multiple non-clustered indexes on a table, but using the code below I can easily add more than one clustered index to my table.
CREATE CLUSTERED INDEX TBL_MULTI_LC_HIST ON dbo.TBL_MULTI_LC_HIST (ID,AsOfDate)
Is this completely wrong?
It isn't possible to create multiple clustered indexes for a single table. From the docs (emphasis mine):
Clustered indexes sort and store the data rows in the table or view based on their key values. These are the columns included in the index definition. There can be only one clustered index per table, because the data rows themselves can be stored in only one order.
For example this will fail:
CREATE TABLE Thing
(
Column1 INT NOT NULL,
Column2 INT NOT NULL
)
CREATE CLUSTERED INDEX IX1 ON dbo.Thing(Column1)
CREATE CLUSTERED INDEX IX2 ON dbo.Thing(Column2)
Error:
Cannot create more than one clustered index on table 'dbo.Thing'. Drop the existing clustered index 'IX1' before creating another.
Example: http://www.sqlfiddle.com/#!18/53a63/1
You can however have a single index with multiple columns in it which is perhaps where you are getting confused:
CREATE CLUSTERED INDEX IX3 ON dbo.Thing(Column1, Column2)
You can only have one clustered index. A "Clustered" index IS the row... it contains all the columns. Every other index would just contain a pointer to the clustered row. The key of the clustered index enforces an 'ordering' on the rows by default.
If there is no clustered index, then the rows are basically stored in a heap, with no order or structure.

Why QO choses clustered index-scan vs table-scan?

If I have a query like this:
SELECT * FROM tTable
where tTable does not contain any indexes a table-scan happens, as expected. If I add a clustered index on some column then QO decides to use clustered index scan on this query. Why? Why is clustered-index-scan preferred instead of table-scan in this case?
If I add a clustered index on some column then QO decides to use clustered index scan on this query
because when you create a clustered index on a table,data in table is rearranged in index order..so table it self is clustered index.This is also the reason why you can't have two clustered indexes on same table
To summarize,when you create a clustered index,there is only one structure ,not two(clustered index and table)
The query is "give me all rows and all columns" which means "read every row" which is a scan
There is nothing to do an index seek on, because there is no WHERE clause.
Unlike this:
SELECT * FROM tTable WHERE PrimaryClusteredKeyValue = 45
Then this may use a nonclustered seek followed by a clustered key lookup or it may still scan the clustered index because you ask for all columns. It depends on how many rows gbn will match
SELECT * FROM tTable WHERE NonClusteredOtherColumnValue = 'gbn'

What is a non-clustered index scan

I know what table scan, clustered index scan and index seek is but my google skills let me down to find a precise explanation into non clustered index scans. Why and when a query uses a non clustered index scan?
Thank you.
As the name suggests, Non Clustered Index Scans are scans on Non Clustered Indexes - NCI scans will typically be done if all of the fields in a select can be fulfilled from a non clustered index, but where the selectivity or indexing of the query is too poor to result in an Seek.
NCI scans potentially have performance benefit over a clustered index scan in that the NCI indexes are generally narrower than the Clustered Indexes (since they generally have fewer columns), hence fewer pages to fetch, and less I/O.
I've put a contrived scenario up on SqlFiddle Here - click on the 'view execution plan' at the bottom.
Given the following setup of table, clustered, and non clustered indexes:
CREATE TABLE Foo
(
FooId INT,
Name VARCHAR(50),
BigCharField CHAR(7000),
CONSTRAINT PK_FOO PRIMARY KEY CLUSTERED(FooId)
);
CREATE NONCLUSTERED INDEX IX_FOO ON Foo(Name);
The following queries demonstrate the different scans:
-- Clustered Index Scan - because we need all fields, CI is most efficient
SELECT * FROM FOO;
-- Non Clustered Index Scan - because we just need Name, but have no selectivity, the NCI
-- will suffice and is narrower.
SELECT DISTINCT(Name) FROM FOO;

Indexing in Sql Server

What is Clustered and non clustered indexing? How to index a table using sql server 2000 Enterprise manager?
In a clustered index on ID, the table rows are ordered by ID.
In a non-clustered index on ID, the references to table rows are ordered by ID.
We can compare a database to a CSV file:
ID,Value
-------
1,ReallyReallyLongValue1
3,ReallyReallyLongValue2
In a clustered table, when we insert a new row, we need to squeeze it between the existing rows:
ID,Value
-------
1,ReallyReallyLongValue1
2,ReallyReallyLongValue2
3,ReallyReallyLongValue3
, which is slow on insert but fast on retrieve.
In a non-clustered table, we keep a separate file index file which orders our rows:
Id,RowNumber
------------
1, 1
3, 2
When we insert the new row, we just append it to our main file and update the short index file:
ID,Value
-------
1,ReallyReallyLongValue1
3,ReallyReallyLongValue3
2,ReallyReallyLongValue2
Id,RowNumber
------------
1, 1
2, 3
3, 2
, which is fast on insert but less efficient on retrieve.
In real databases indexes use more efficient binary trees, but the principle remains the same.
Clustered indexes are faster on SELECT, non-clustered indexes are faster on INSERT / UPDATE / DELETE
A clustered index means that the rows are physically ordered by the values in that index. A non-clustered index means that an index table is kept up to date that allows for quick seeking and sorting based upon value, but does not physically order the rows.
Only one clustered index can exist for a table, and if a primary key exists then that is the clustered index (in SQL Server).
A clustered index defines how the actual table is stored. The rows are stored in a way to make searches on the fields in the clustered index fast. (They're not physically stored in the sort order of the index fields, but in a binary tree or something similiar.)
You can have only one clustered index per table. The clustered index contains all fields in the table, for example:
indexfield1 - indexfield2 - field2 - field3 - ....
A non-clustered index is like a separate table. It contains the fields in the index, and a reference to the fields in the table. For example:
secondindexfield1 - secondindexfield2 - reference to table row
When searching a non-clustered index, SQL server will find the value in the index, do a "bookmark lookup" to the table, and retrieve the other row fields from there. This is why non-clustered indexes perform slightly less wel then clustered indexes.
To add an index in SQL Server Management Studio, expand the table node in object view. Right click on "Indexes" and select "New Index".
Clustered Index: Only one clustered index per table is allowed. If an index is clustered, it means that the table on which the clustered index is based is physically sorted according to that index. Think of the page numbers in an encyclopedia.
Non-clustered Index: Can have many non-clustered indexes per table. Think of the keyword index at the back of the book.

Resources