Unique clustered index on two columns for an indexed view - sql

I'm trying to setup an indexed view on a table that doesn't have a unique id. It has two unique identifiers that if combined would be unique for it's row. I'm having trouble actually creating the unique clustered index that the indexed view requires when I found an thread on MSDN that folks all agree it is possible to create a unique clustered index out of 2 columns for a indexed view # http://social.msdn.microsoft.com/Forums/en/transactsql/thread/f2c99845-3af1-46e8-9b52-363c24988744
But for the life of me, can't figure out how to create it. I'm rolling with this query, but it doesn't seem to cut it.
CREATE UNIQUE CLUSTERED INDEX [PK] ON MyView
(
MyId1, MyId2
)
Error:
The CREATE UNIQUE INDEX statement terminated because a duplicate key
was found for the object name 'dbo.MyView' and the index name 'PK'.
The duplicate key value is (71cd9b68-1a9e-47bc-bc6b-0008b230a6d8,
0e64aa3a-0631-4caf-82d9-73609ee79b19).
The two IDs listed as duplicates are IDs from MyId2.
So, how could I create a unique clustered index here?

Well the error message seems to suggest that there is more than one record where MyId1 = 71cd9b68-1a9e-47bc-bc6b-0008b230a6d8 and MyId2 = 0e64aa3a-0631-4caf-82d9-73609ee79b19.
I would recommend running a query that selects based only on that criteria and confirming that this only returns one record. If it returns more, then you cannot recreate a UNIQUE constraint on these two columns unless you eliminate the duplicates.

Related

PostgreSQL: unique constraint or unique index

Should I create unique index if a column contains unique constraint and I want to fast search by this column?
For example I have a table users with column login that should be unique. I need fast search user by the login column.
Which is the best way to do it:
create a unique constraint (it creates internal unique index - is it used in select queries with WHERE login = 'something'?)
create a unique index
create a unique index and unique constraint (index duplicates internal index?)
Second case is unique login on not locked users (column locked = false). Postgres does not support partial conditions. Should I create a unique conditional and a partial index or is only a partial index enough?
And one more question: should I create new index for a column with a foreign key? For example: users.employee_id relates to employees.id, should I create an index on employee column for optimized query SELECT * FROM users WHERE employee_id = ....? When are internal indexes used by the optimization engine and when not?
I have a table 'users' with column login that should be unique
If this is the case you need a unique constraint. Unique constraints are enforced (behind the scenes) by unique indexes.
Conceptually:
The unique constraint defines the uniqueness.
The unique index implements the unique constraint.
The unique index provides speedy searches since it allows operations such as Index Range Scan and Index Seeks.
Is it used in select queries with WHERE login = 'something'?
Yes, it is.
Second case is unique login on not locked users (column locked = false).
If this is the case a unique constraint won't work. Maybe a trigger on insert could help here.
should I create new index for column with foreign key?
No, it's not needed (at least in the current version 10 and perhaps the later versions), s. documentation:
PostgreSQL automatically creates a unique index when a unique constraint or primary key is defined for a table. [...] There's no need to manually create indexes on unique columns; doing so would just duplicate the automatically-created index.

SQL: Add Primary Key to Non-Unique Index

Let's say a query is filtering on two fields and returning primary key values.
SELECT RowIdentifier
FROM Table
WHERE QualifierA = 'exampleA' AND QualifierB = 'exampleB'
Assuming the clustered index is not the PrimaryKey would a non-unique index that contains QualifierA and QualiferB be best served via the addition of the RowIdentifier(Scenario A & Scenario B). Or would it be more appropriate to simply include it(Scenario C)?
Scenario A: Non-Unique, Non-Clustered
CREATE NONCLUSTERED INDEX IX_Table_QualifierA
ON [dbo].[Table] ([QualifierA],[QualifierB],[RowIdentifier])
Scenario B: Unique, Non-Clustered
CREATE UNIQUE NONCLUSTERED INDEX IX_Table_QualifierA
ON [dbo].[Table] ([QualifierA],[QualifierB],[RowIdentifier])
Scenario C:
CREATE NONCLUSTERED INDEX IX_Table_QualifierA
ON [dbo].[Table] ([QualifierA],[QualifierB])
INCLUDE ([RowIdentifier])
Finally I'm assuming that if the PrimaryKey were the clustered index that neither is necessary, is this accurate?
If there is a CLUSTERED index, it is automatically included in all indexes on the table. You can explicitly include it but it is not required.
The UNIQUE index simply enforces uniqueness. The PK should already have this constraint. You do not need to re-enforce it in every index.
If you are including the PK in your where clause, it will almost certainly use the PK index to find that row because it is guaranteed to return the fewest results, so including in your index gains you nothing for lookups. It could also potentially skew the cardinality engine and make SQL think the index is more distinct than it really is.
For the above reasons, I would select Option C
CREATE NONCLUSTERED INDEX IX_Table_QualifierA
ON [dbo].[Table] ([QualifierA],[QualifierB])
INCLUDE ([RowIdentifier])
I would use this regardless of what column is clustered. This will give you the performance, insure the index will continue to perform regardless of the CLUSTERED INDEX, and make it explicit what the index is used for.
I'm wondering what's more appropriate? A non-clustered unique index incorporating all three fields, or a non-clustered non-unique index incorporating just the two fields(QualifierA & QualifierB) but including the PrimaryKey.
There's a third option. A non-clustered, non-unique index incorporating all three fields.
When you make an index, the fields in the index are duplicated to another place in memory so the server can go after those fields with ease. If you only have QualiferA and Qualifier B in the index it will find the rows in that index that meet your criteria and then go back to the main table to pick up the RowIdentifier. Instead, include all three in there to improve performance.
Remember, make sure you put QualifierA and QualifierB before RowIdentifier in your index. The order of the columns determine how the data is ordered.
Try it out with some test data if you like, and look at the query plan to see what it's doing.

What is the difference between a primary key and an index when it comes to inserting records?

I have to insert data into a table that has a PK in it. I also have another table that has a clustered index in it.
Should I drop the PK or the INDEX for the the best INSERT speeds? Then recreate them afterwards?
I load data to these types of tables on a routine basis and I want to make sure I am using the quickest way possible in all situations.
A primary key uniquely identifies a record and has other uses as well. An index makes select queries run faster.
You should never drop your primary key.
Whether or not you drop and re-create indexes when adding records depends on the circumstances.
Primary Key : Uniquely identifies the the data & we cannot insert duplicate Data.
Index : Index help us to get out data to us very quickly.
Very Important Concept about Primary key & Index
Suppose your column is marked with the primary key then Clustered Index automatically gets created,
If no clutstered index is already present in the table
To See that Your Index is Created Successfully, You can use.
sp_helpindex Index_Name
- About Index :
You cannot create a unique index on a single column if that column contains NULL in more than one row. Similarly, you cannot create a unique index on multiple columns if the combination of columns contains NULL in more than one row. These are treated as duplicate values for indexing purposes.
- About Primary Key :
All columns defined within a PRIMARY KEY constraint must be defined as NOT NULL. If nullability is not specified, all columns participating in a PRIMARY KEY constraint have their nullability set to NOT NULL.

In SQL Server, should all bridge table fields have indexes on them?

I have read that all foreign keys should be indexed for better join performance. Do that mean, by definition, that all bridge tables should have all fields indexed
for example lets say i have 3 table
Project: Id, Name
ProjectApplication: Id, ProjectId, ApplicationId
Application: Id, Name
in these cases, should ProjectId and ApplicationId both have indexes on them?
In your given example Id column in Project table have to be a Primary key(or atleast UNIQUE constraint) in order to be able to reference it in any other column i.e creating a foreign key constraint which references it same is true for Id column in Application table. So by default it will have a Clustered Index defined on it.
Now in your ProjectApplication table if you do create a foreign Key and create an Index on that column, and obviously when ever you need to retrieve information from these tables you will be joining these tables on these two fields so having a Clustered Index on one side and a nonclustered index on other side will most definitely have a great impact on the performance of your queries, well worth it , go for it .

UNIQUE argument for INDEX creation - what's for?

Why does INDEX creation statement have UNIQUE argument?
As I understand, the non-clustered index contains a bookmark, a pointer to a row, which should be unique to distinguish even non-unique rows,
so insuring non-clustered index to be unique ?
Correct?
So, do I understand that no-unique index can be only on clustered table? since
"A clustered index on a view must be unique" [1]
Since "The bottom, or leaf, level of the clustered index contains the actual data rows of the table" [1], do I understand correctly that the same effect as UNIUE on clustered index can be achieved by unique constraint on (possibly all or part of) columns of a table [2]?
Then, what does bring UNIQUE argument for index?
except confusion to basic concepts definitions [3]
Update:
This is again the same pitfall - explaining something already explained many times based on undefined terms converting all explanation to never-ending guessing game.
Please see my subquestion [4] which is really re-wording of this same question here.
Update2:
The problem is in ambiguous, lacking definitions or improper use of terms in improper contexts. If index is defined as structure serving to (find and) identify/point to real data, then non-unique or NULL indexes do not make any sense. Bye
Cited:
[1]
CREATE INDEX (Transact-SQL)
http://msdn.microsoft.com/en-us/library/ms188783.aspx
[2]
CREATE TABLE (Transact-SQL)
http://msdn.microsoft.com/en-us/library/ms174979.aspx
[3]
Unique index or unique key?
Unique index or unique key?
[4]
what is index and can non-clustered index be non-unique?
what is index and can non-clustered index be non-unique?
While a non-unique index is sufficient to distinguish between rows (as you said), the UNIQUE index serves as a constraint: it will prevent duplicates from being entered into the database - where "duplicates" are rows containing the same data in the indexed columns.
Example:
Firstname | Lastname | Login
================================
Joe | Smith | joes
Joe | Taylor | joet
Susan | Smith | susans
Let's assume that login names are by default generated from first name + first letter of last name.
What happens when we try to add Joe Sciavillo to the database? Normally, the system would happily generate loginname joes and insert (Joe,Sciavillo,joes). Now we'd have two users with the same username - probably a Bad Thing.
Now let's say we have a UNIQUE index on Login column - the database will check that no other row with the same data already exists, before it allows inserting the new row. In other words, the attempt to insert another joes will be rejected, because that data wouldn't be unique in that row any more.
Of course, you could have unique indexes on multiple columns, in which case the combination of data would have to be unique (e.g. a unique index on Firstname,Lastname will happily accept a row with (Joe,Badzhanov), as the combination is not in the table yet, but would reject a second row with (Joe,Smith))
The UNIQUE index clause is really just a quirk of syntax in SQL Server and some other DBMSs. In Standard SQL, uniqueness constraints are implemented through the use of the PRIMARY KEY and UNIQUE CONSTRAINT syntax, not through indexes (there are no indexes in standard SQL).
The mechanism SQL Server uses internally to implement uniqueness constraints is called a unique index. A unique index gets created automatically for you whenever you create a PRIMARY KEY or UNIQUE constraint. For reasons best known to the SQL Server development team they decided to expose the UNIQUE keyword as part of the CREATE INDEX syntax, even though the constraint syntax does the same job.
In the interests of clarity and standards support I would recommend you avoid creating UNIQUE indexes explicitly wherever possible. Use the PRIMARY KEY or UNQIUE constraint syntax instead.
The UNIQUE clause specifies that the values in the column(s) must be unique across the table, essentially adding a unique constraint. A clustered index on a table specifies that the ordering of the rows in the table will be the same as the index. A non-clustered index does not change the physical ordering, which is why it is OK to have multiple non-clustered but only one clustered index. You can have unique or non-unique clustered and non-clustered indexes on a table.
I think the underlying question is: what is the difference between unique and non-unique indexes?
The answer is that entries in unique indexes can each only point to a single row, while entries in non-unique indexes can point to many rows.
For example, consider an order item table:
ORDER_NO INTEGER
LINE_NO INTEGER
PRODUCT_NO INTEGER
QUANTITY DECIMAL
- with a unique index on ORDER_NO and LINE_NO, and a non-unique index on PRODUCT_NO.
For a single combination of ORDER_NO and LINE_NO there can only be one entry in the table, while for a single value of PRODUCT_NO there can be many entries in the table (because there will be many entries for that value in the index).