Using MySQL 5.7, I have a table of urls containing url_title, url_description, url_keywords
Sometimes I just need to look in url_title, but sometimes look for something in all columns.
Is it better to just create one index containing all 3 columns or create a separate index for url_title alone and another index containing all 3 columns ?
e.g Will it search for url_title slower in the 3 columns index vs single column ?
Or can MySQL only search/read in given column even if index would contain 3 columns ?
Later edit: this is a sample query but I do have other less important variations:
SELECT *
FROM urls
WHERE match(url_title, url_description,
url_keywords, url_paragraphs)
against('red boots' IN BOOLEAN MODE)
LIMIT 500
2
Answers
Update: You didn’t mention in your original post that you were talking about fulltext indexes, not conventional B-tree indexes.
Fulltext indexes are a different type. You must specify ALL the columns of the fulltext index in your
MATCH()
clause. No fewer, and no more, and they must be in the same order as they appear in the index definition.If you want to do a fulltext search only on a single column sometimes, then you will have to create another fulltext with that single column.
Below is my original answer, that I wrote before you clarified that you were using a fulltext index. Perhaps it will help someone else.
MySQL can use the index if the column(s) you search are the leftmost column(s) of that index. It can use a subset of the columns of a multi-column index.
For example, given an index on
(a, b, c)
, the following query uses all three columns:The following query uses the first column
a
of the index, because it’s the leftmost column.The following query uses the first two columns of the index, because they’re consecutive and the leftmost subset of columns.
The following query uses only the first column
a
of the index, because the conditions don’t match consecutive columns of the index. It will use the index to narrow down the search to rows matching thea
condition, but then it will have to examine each of those rows to evaluate thec
condition, even thoughc
is part of the same index.MySQL has an optimization called index condition pushdown which does a short-cut for this. It delegates to the storage engine to evaluate the
c
condition, knowing thatc
is part of the index. So it still counts as examining the row, but it make the row read a little bit less costly.The following query cannot use the index at all, because the conditions are not on leftmost columns of that index.
The guidelines for
FULLTEXT
indexes andMATCH...AGAINST
are different than forINDEX
. For this:(and assuming
ENGINE=InnoDB
), you need aFULLTEXT
index with all 4 columns in it.If you might also be searching, say, just
url_title
in another query, then you would also needFULLTEXT(url_title)
. (Etc)See if either of these would be ‘better’ for your application: