Q: When does it make sense to create an index?
We create indexes for basically two reasons 1) to enforce UNIQUE constraints and 2) improve performance and reduce contention. (In terms of PostgreSQL, when we declare a UNIQUE CONSTRAINT, the database automatically creates a UNIQUE INDEX.)
Q: Is that understanding correct?
Not entirely, no. When we execute a query with predicate WHERE col = 'somevalue'
, without an index, the database will need to evaluate every row in the table. And on very large table, that can be a significant amount of work. With an appropriate index available the execution plan can eliminate vast swaths of rows that would otherwise need to be checked. That's where we get the real performance boost.
Think of this analogy. When we lookup a word in the dictionary, if the entries are not "in order", we would start looking at every entry in the dictionary, and compare the word we are looking for to each and every entry, until we found a match.
Fortunately, in most dictionaries, entries sorted in alphabetical order. we can make effective use of that, and very quickly eliminate a whole lot of pages from consideration, and save ourselves a lot of time. If we are looking for the word 'ostensibly', we know we can start at "O". We can "skip over" all of the entries on pages with words starting with A, B, ..., N, and also "skip over" all of the pages for words starting with P, Q, ..., Z.
In a similar way, the database engine can save a lot of work, making use of an index to "skip over" a whole lot of pages that it knows can't contain the row(s) it is looking for.
Q: ... indexes by default on its own..?
For the PRIMARY KEY constraint, yes, PostgreSQL automatically creates an index.
For a UNIQUE CONSTRAINT, yes, PostgreSQL automatically creates an index.
All other indexes must be declared (created) explicitly.
We typically want to create indexes on foreign keys, and on columns (or expressions, or sets of columns) with leading columns that have high cardinality/high selectivity and are referenced in predicates that are sargable.
Appropriate indexes can significantly improve performance; but indexes also come at a cost... there's additional storage and processing for index maintenance, so we shouldn't create singleton column indexes willy nilly. Care should be taken to evaluate the actual queries that are being executed (or we plan to execute) and implement indexes that most effectively support those operations.