How do you get MySQL to use an index to query a view? Short answer, indicate the index that MySQL can use.
In this case, the optimal index is probably the "covering" index:
... ON highscores (player, happened_in, score)
MySQL will probably use this index, and EXPLAIN will show: "Using index" due to WHERE player = 24 (equality predicate in the leading column of the index. GROUP BY happened_id (second column in the index), may allow MySQL to optimize this using the index to avoid the sorting operation By including the score column in the index, you can fully execute the query from the index without visiting (searching) the data page that the index refers to.
This is a quick answer. The longer answer is that MySQL is unlikely to use an index with a leading column of happened_id to query the view.
Why performance causes performance issues
One of the problems you encounter with a MySQL view is that MySQL does not “push” a predicate from an external query into a query of the form.
In your outer query, WHERE happened_in = 2006 indicated. The MySQL optimizer does not account for a predicate when it runs an internal view request. This request for presentation is executed separately, before an external request. The result from the execution of this query is "materialized"; that is, the results are saved as a MyISAM staging table. (MySQL calls this a "view", and the name they use makes sense when you understand the operations performed by MysQL.)
The bottom line is that the index that you defined on happened_in is not used by MySQL when it processes the query that forms the definition of the view.
After creating the THEN intermediate “view”, an external query is executed using this “view” as the row source. This is when this external query is executed, the predicate happened_in = 2006 is evaluated.
Note that all rows from a query of the form are stored, which (in your case) is a string for EVERY value happened_in , and not just the one you specify in the equality predicate in the outer query.
The way in which view requests are processed may be "unexpected" for some, and this is one of the reasons that using "views" in MySQL can lead to performance problems compared to how request requests are handled by other relational databases.
Improving view query performance with a suitable coverage index
Given your view definition and your request, the best way to get it will be to use the Index Usage access method to request the view. To get this, you need a coverage index, for example.
... ON highscores (player, happened_in, score).
This is most likely the most useful index (in terms of performance) for your existing definition definition and your existing query. The column player is the leading column because you have an equality predicate in this column in the view request. The happened_in column is as follows because you have a GROUP BY operation in this column, and MySQL will be able to use this index to optimize the GROUP BY operation. We also include the score column because this is the only column that your query refers to. This makes the index a “closing” index, because MySQL can satisfy this query directly from the index pages, without having to visit any pages in the base table. And this is as good as we are going to get out of this query plan: "Use index" without "Using filesort".
Performance comparison with offline query without a view
You can compare the execution plan of your request with a view against an equivalent stand-alone request:
SELECT player , MAX(score) AS highest_score , happened_in FROM highscores WHERE player = 24 AND happened_in = 2006 GROUP BY player , happened_in
A standalone query can also use a coverage index, for example.
... ON highscores (player, happened_in, score)
but without the need to materialize the MyISAM staging table.
I am not sure if any of the previous ones gives a direct answer to the question that you asked.
Q: How to force MySQL to use the INDEX query to view?
A: Define a suitable index that can use a view query.
The short answer is a “coverage index” (the index includes all the columns referenced by the query request). The leading columns in this index should be the columns referenced by equality predicates (in your case, the player column will be the leading column, because the query has the predicate player = 24 Also, the columns referenced in GROUP BY should be leading columns in the index, which allows MySQL to optimize the GROUP BY operation using an index rather than using a sort operation.
The key point here is that the view request is basically an offline request; the results of this query are stored in an intermediate “derived” table (the MyISAM table created when the view request is run.
Using views in MySQL is not necessarily a “bad idea,” but I would strongly caution those who choose to use views in MySQL to KNOW how MySQL handles queries that reference these views. And the method of processing MySQL query requests differs (significantly) from the way view queries are processed by other databases (for example, Oracle, SQL Server).