MySQL vs MariaDB – Do They Have SQL Server’s ‘Included Columns’ for Indexes?

indexmariadbMySQL

In SQL Server you can create an index and have additional columns included on that index that can help performance in certain circumstances. Is that same ability available for mysql or mariadb under a different name, perhaps? I was unable to find anything using the term "included columns".

Best Answer

Looking at the MySQL Documentation, the glossary indicates this about Covering Indexes:

An index that includes all the columns retrieved by a query. Instead of using the index values as pointers to find the full table rows, the query returns values from the index structure, saving disk I/O. InnoDB can apply this optimization technique to more indexes than MyISAM can, because InnoDB secondary indexes also include the primary key columns. InnoDB cannot apply this technique for queries against tables modified by a transaction, until that transaction ends.

Any column index or composite index could act as a covering index, given the right query. Design your indexes and queries to take advantage of this optimization technique wherever possible.

The implication here is that there is no direct equivalent of an INCLUDE statement in MySQL, however if the index provides coverage of the columns involved in an index, it can, rather obviously, still be considered to be covering, much like an index with included columns in SQL Server would be.

MariaDB has the following in their documentation for covering indexes:

A "Covering" index is an index that contains all the columns in the SELECT. It is special in that the SELECT can be completed by looking only at the INDEX BTree. (Since InnoDB's PRIMARY KEY is clustered with the data, "covering" is of no benefit when considering at the PRIMARY KEY.)

Mini-cookbook:

  1. Gather the list of column(s) according to the "Algorithm", above.
  2. Add to the end of the list the rest of the columns seen in the SELECT, in any order.

Examples:

SELECT x FROM t WHERE y = 5; ⇒ INDEX(y,x) -- The algorithm said just INDEX(y)  
SELECT x,z FROM t WHERE y = 5 AND q = 7; ⇒ INDEX(y,q,x,z) -- y and q in either order (Algorithm), then x and z in either order (covering).  
SELECT x FROM t WHERE y > 5 AND q > 7; ⇒ INDEX(y,q,x) -- y or q first (that's as far as the Algorithm goes), then the other two fields afterwards.   

The speedup you get might be minor, or it might be spectacular; it is hard to predict.

But...

  • It is not wise to build an index with lots of columns. Let's cut it off at 5 (Rule of Thumb).
  • Prefix indexes cannot 'cover', so don't use them anywhere in a 'covering' index.
  • There are limits (3KB?) on how 'wide' an index can be, so "covering" may not be possible.