Skip to content

Commit

Permalink
Add explanation about implicit indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
greg0ire committed Sep 12, 2020
1 parent f97ee94 commit c179c01
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 2 deletions.
46 changes: 46 additions & 0 deletions docs/en/explanation/implicit-indexes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Implicit indexes
================

So-called implicit indexes are named as such because they are created
without the user asking for it. Some RDBMS will do so when you create a
foreign key: they will create an index on the referencing table, using
the referencing columns.

The rationale behind this is that these indexes improve performance, for
instance for checking that a delete operation can be performed on a
referenced table without violating the constraint in the referencing
table.


Here are some database platforms that are known to create indexes when
creating a foreign key:

- `MySQL <https://dev.mysql.com/doc/refman/8.0/en/create-table-foreign-keys.html>`_
- `MariaDB <https://mariadb.com/kb/en/foreign-keys>`_


Some other will not do so, on grounds that such indexes are not always
needed, and can be created in many different ways. They instead leave
that responsibility to the user:

- `PostgreSQL <https://stackoverflow.com/questions/970562/postgres-and-indexes-on-foreign-keys-and-primary-keys>`_
- `SQLite <https://sqlite.org/foreignkeys.html#fk_indexes>`_
- `SQL Server <https://stackoverflow.com/questions/836167/does-a-foreign-key-automatically-create-an-index>`_

In the case of these systems, the DBAL does the index creation for you
and automatically picks an index name that obeys string length
constraints of the platform you are using. That way, differences between
platforms is reduced because you always end up with an index, be it
created by the RDBMS or by the DBAL. This is a detail, but these indexes
will be prefixed with ``IDX_``, and typically look like this:

.. code-block:: sql
CREATE INDEX IDX_885DBAFAA76ED395 ON posts (user_id)
You can still explicitly create such indexes yourself, and the DBAL will
notice when your index fulfills the indexing and constraint needs of the
implicit index it would create, and will refrain from doing so.

Some RDBMS such as MySQL do something similar and can also drop implicit
indexes that are fulfilled by user-defined indexes.
2 changes: 2 additions & 0 deletions docs/en/sidebar.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@
reference/caching
reference/known-vendor-issues
reference/upgrading

explanation/implicit-indexes
4 changes: 2 additions & 2 deletions lib/Doctrine/DBAL/Schema/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -554,8 +554,8 @@ protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint)

$this->_fkConstraints[$name] = $constraint;

// Add an explicit index on the foreign key columns.
// If there is already an index that fulfils this requirements drop the request.
// Add an implicit index on the foreign key columns.
// If there is already an index that fulfills these requirements drop the request.
// In the case of __construct calling this method during hydration from schema-details
// all the explicitly added indexes lead to duplicates. This creates computation overhead in this case,
// however no duplicate indexes are ever added (based on columns).
Expand Down

0 comments on commit c179c01

Please sign in to comment.