I created a table named STUDENT. It has the following columns:
Id
Name
Surname
DateOfBirth
DateOfAdmission
DateOfPassout
This table have following primary key:
Id
Name
Surname
DateOfAdmission
Do I need to create an index another index of column Id, Name if want to query this table providing input just Id and Name?
An index isn't necessary for queries.
An index has the potential to speed up queries if the index can be used, but will slow down INSERT/UPDATE/DELETE statements.
I'm not clear when Oracle started, but Oracle 10g+ will automatically create an index when a primary key is defined for a table. That index will match the column(s) that make up the primary key. Being that the id and name columns are part of the primary key, the pair is guaranteed to be unique and I don't see the need to create an additional covering index.
Related
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.
I have a table with structure shown below :-
CREATE TABLE IF NOT EXISTS tblvideolikes (
itemid SERIAL PRIMARY KEY,
videoid integer NOT NULL,
userid integer NOT NULL,
CONSTRAINT liked_video_user UNIQUE(videoid,userid)
)
I have a lot of select queries with userid and videoid. I want to know whether adding unique constraint on both columns are sufficient or Do I need to do indexing on both of them as well. I have searched a lot about this but nothing makes it clear.
If you have to enforce the unique combination of both columns, you have to create the unique index on both of them.
Postgres will use that index as well if your where clause only has a condition on the first column of the index (the usual "it depends" on index usage still applies here).
Postgres is able to use a column that is not the leading column of an index for a where condition - however that is less efficient then using a leading column.
I would put that column first that is used more often as single where condition. The order of the columns does not matter for the uniqueness.
If the usage of (only) the second column is as frequent as using the (only) first column, then adding an additional index with only the second column could make sense, e.g.:
CREATE TABLE IF NOT EXISTS videolikes (
itemid SERIAL PRIMARY KEY,
videoid integer NOT NULL,
userid integer NOT NULL,
CONSTRAINT liked_video_user UNIQUE(videoid,userid)
);
create index on videolikes (userid);
The unique index would then be used for conditions on only videoid and (equality) conditions using both columns. The second index would be used for conditions on only the userid
Unrelated, but:
The itemid primary key is pretty much useless with the above setup. You needlessly increase the size of the table and add another index that needs to be maintained. You can simply leave it out and declare videoid, userid as the primary key:
CREATE TABLE IF NOT EXISTS videolikes (
videoid integer NOT NULL,
userid integer NOT NULL,
CONSTRAINT pk_videolikes primary key (videoid,userid)
);
create index on videolikes (userid);
Indexing on both the column separately is a better idea if you are going to do frequent queries from both sides.
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 .
This can be a silly question but I want to be sure 100%.
Is the PK of a DB2 table a clustered index by default?
From: DB2 docs - Clustering indexes
Although a table can have several indexes, only one index can be a clustering index. If you do not define a clustering index for a table, DB2 recognizes the first index that is created on the table as the implicit clustering index when it orders data rows.
So no, by default the Primary Key is NOT the clustered index of the table.
The first created index, unique or not, is the "implicit" clustering index and DB2 tries to insert the records as nearly as possible in the order of the values of this index.
If you later create another index and identify it as clustering, then DB2 identifies it as the clustering index but does not rearrange the data that is already in the table. This can be done with the REORG utility.
From the Publib (this assumes DB2 for z/OS, version 9)
When a table has a clustering index, an INSERT statement causes DB2 to
insert the records as nearly as possible in the order of their index
values. The first index that you define on the table serves implicitly
as the clustering index unless you explicitly specify CLUSTER when you
create or alter another index. For example, if you first define a
unique index on the EMPNO column of the EMP table, DB2 inserts rows
into the EMP table in the order of the employee identification number
unless you explicitly define another index to be the clustering index.
You can see which index is the clustering index for a table (in this example, TEST.TABLE1) using the following query, if you're on z/OS:
SELECT NAME
FROM SYSIBM.SYSINDEXES
WHERE TBCREATOR = 'TEST'
AND TBNAME = 'TABLE1'
AND CLUSTERING = 'Y'
And this one for Linux/Unix/Windows (LUW):
SELECT *
FROM SYSCAT.INDEXES
WHERE TABSCHEMA = 'TEST'
AND TABNAME = 'TABLE1'
AND INDEXTYPE = 'CLUS'
DB2 doesn't create clustered index for a PK by default.
Primary keys
A primary key is a special type of unique key and cannot contain null values. For example, the DEPTNO column in the DEPT table is a primary key.
A table can have no more than one primary key. Primary keys are optional and can be defined in CREATE TABLE or ALTER TABLE statements.
The unique index on a primary key is called a primary index. When a primary key is defined in a CREATE TABLE statement or ALTER TABLE statement, DB2 automatically creates the primary index if one of the following conditions is true:
DB2 is operating in new-function mode, and the table space is implicitly created.
DB2 is operating in new-function mode, the table space is explicitly created, and the schema processor is running.
DB2 is operating in conversion mode, and the schema processor is running.
If a unique index already exists on the columns of the primary key when it is defined in the ALTER TABLE statement, this unique index is designated as the primary index when DB2 is operating in new-function mode and implicitly created the table space.
See at: Keys DB2
I am facing here a problem with a SQL statement, which fetches the data from table called News according to category :
News : Id(PK) int, Title string, Subject string, Uid int, Cid int.
SELECT Id, Subject, Uid, Title FROM News WHERE Uid = #Uid
This statement operates slowly comparing to statement without WHERE since it should go and check every single row to ensure if it is accomplish the condition.
So imagine with me the table News with 10000000 article. What should I do about such a thing?
If the Id column is a primary key that might already be clustered (they are by default), you just need to create a non-clustered index on the Uid column - especially of the Uid column is a uniqueidentifier (GUID) data type.
This can be created by running the following SQL:
CREATE NONCLUSTERED INDEX IX_News_Uid ON News
(
Uid
)
You should create an index for the column Uid, with Id, Subject and Title as included columns.
That way the database can run the query using only the index, and doesn't have to touch the table at all.
I would create an unique index on Uid.
You should could create a clustered index on the Uid column. This should improve performance. Note: You can only have one clustered index column per table.