Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9005359
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T01:07:27+00:00 2026-06-16T01:07:27+00:00

I’m working on a web project with MySql database on Java EE. We needed

  • 0

I’m working on a web project with MySql database on Java EE. We needed a view to summarize data from 3 tables with over 3M rows overall. Each table was created with index. But I haven’t found out a way to take advantages in the indexes in the conditional select statement retrieval from the view that we created with [group by].

I’ve getting suggestions from people that using views in MySql is not a good idea. Because you can’t create index for views in mysql like in oracle. But in some test that I took, indexes can be used in view select statement. Maybe I’ve created those views in a wrong way.

I’ll use a example to describe my problem.

We have a table that records data for high scores in NBA games, with index on column [happend_in]

CREATE  TABLE `highscores` (
   `tbl_id` int(11) NOT NULL auto_increment,
   `happened_in` int(4) default NULL,
   `player` int(3) default NULL,
   `score` int(3) default NULL,
   PRIMARY KEY  (`tbl_id`),
   KEY `index_happened_in` (`happened_in`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert data(8 rows)

INSERT INTO highscores(happened_in, player, score)
VALUES (2006, 24, 61),(2006, 24, 44),(2006, 24, 81),
(1998, 23, 51),(1997, 23, 46),(2006, 3, 55),(2007, 24, 34), (2008, 24, 37);

then I create a view to see the highest score that Kobe Bryant got in each year

CREATE OR REPLACE VIEW v_kobe_highScores
AS
   SELECT player, max(score) AS highest_score, happened_in
   FROM highscores
   WHERE player = 24
   GROUP BY happened_in;

I wrote a conditional statement to see the highest score that kobe got in 2006;

select * from v_kobe_highscores where happened_in = 2006;

When I explain it in toad for mysql, I found out that mysql have scan all rows to form the view, then find data with condition in it, without using index on [happened_in].

explain select * from v_kobe_highscores where happened_in = 2006;

explain result

The view that we use in our project is built among tables with millions of rows. Scanning all the rows from table in every view data retrieval is unacceptable. Please help! Thanks!

@zerkms Here is the result I tested on real-life. I don’t see much differences between. I think @spencer7593 has the right point. The MySQL optimizer doesn’t “push” that predicate down in the view query.
real-life test

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T01:07:28+00:00Added an answer on June 16, 2026 at 1:07 am

    How do we get MySQL (or MariaDB) to use an index for a view query? The short answer, we provide an index that MySQL can use.

    In this case, the optimum index is likely a "covering" index:
    Likely, the optimum index will turn out to be a "covering index" e.g.

    CREATE INDEX highscores_IX3
    ON highscores (player, happened_in, score)

    and we expect MySQL optimizer will be able to use that index for the SELECT. We test just the SELECT first (without the CREATE VIEW) and EXPLAIN will show: "Using index" due to the WHERE player = 24 (in database lingo, that’s an equality predicate on the leading column in the index. The GROUP BY happened_id (the second column in the index), may allow MySQL to avoid a (potentially expensive) sort operation, allowing the rows to be returned in order from the index.

    Including the score column in the index will allow the query to satisfied entirely from the index pages, without having to visit (lookup) the data pages referenced by the index.

    That’s the quick answer. The longer answer is that MySQL is very unlikely to use an index with leading column of happened_id for the view query.


    Why the view causes a performance issue

    One of the issues you have with the MySQL view is that MySQL does not "push" the predicate from the outer query down into the view query.

    Your outer query specifies WHERE happened_in = 2006. The MySQL optimizer does not consider the predicate when it runs the inner "view query". That query for the view gets executed separately, before the outer query. The resultset from the execution of that query get "materialized"; that is, the results are stored as an intermediate MyISAM table. (MySQL calls it a "derived table", and that name they use makes sense, when you understand the operations that MysQL performs.)

    The bottom line is that the index you have defined on happened_in is not being used by MySQL when it rusn the query that forms the view definition.

    After the intermediate "derived table" is created, THEN the outer query is executed, using that "derived table" as a rowsource. It’s when that outer query runs that the happened_in = 2006 predicate is evaluated.

    Note that all of the rows from the view query are stored, which (in your case) is a row for EVERY value of happened_in, not just the one you specify an equality predicate on in the outer query.

    The way that view queries are processed may be "unexpected" by some, and this is one reason that using "views" in MySQL can lead to performance problems, as compared to the way view queries are processed by other relational databases.


    Improving performance of the view query with a suitable covering index

    Given your view definition and your query, about the best you are going to get would be a "Using index" access method for the view query. To get that, you’d need a covering index, e.g.

    ... ON highscores (player, happened_in, score).
    

    That’s likely to be the most beneficial index (performance wise) for your existing view definition and your existing query. The player column is the leading column because you have an equality predicate on that column in the view query. The happened_in column is next, because you’ve got a GROUP BY operation on that column, and MySQL is going to be able to use this index to optimize the GROUP BY operation. We also include the score column, because that is the only other column referenced in your query. That makes the index a "covering" index, because MySQL can satisfy that query directly from index pages, without a need to visit any pages in the underlying table. And that’s as good as we’re going to get out of that query plan: "Using index" with no "Using filesort".


    Compare performance to standalone query with no derived table

    You could compare the execution plan for your query against the view vs. an equivalent standalone query:

    SELECT player
         , MAX(score) AS highest_score
         , happened_in
     FROM highscores
    WHERE player = 24
      AND happened_in = 2006
    GROUP
       BY player
        , happened_in
    

    The standalone query can also make use of a covering index e.g.

    ... ON highscores (player, happened_in, score)
    

    but without a need to materialize an intermediate MyISAM table.


    I am not sure that any of the previous provides a direct answer to the question you were asking.

    Q: How do I get MySQL to use an INDEX for view query?

    A: Define a suitable INDEX that the view query can use.

    The short answer is provide a "covering index" (index includes all columns referenced in the view query). The leading columns in that index should be the columns that are referenced with equality predicates (in your case, the column player would be a leading column because you have a player = 24 predicate in the query. Also, the columns referenced in the GROUP BY should be leading columns in the index, which allows MySQL to optimize the GROUP BY operation, by making use of the index rather than using a sort operation.

    The key point here is that the view query is basically a standalone query; the results from that query get stored in an intermediate "derived" table (a MyISAM table that gets created when a query against the view gets run.

    Using views in MySQL is not necessarily a "bad idea", but I would strongly caution those who choose to use views within MySQL to be AWARE of how MySQL processes queries that reference those views. And the way MySQL processes view queries differs (significantly) from the way view queries are handled by other databases (e.g. Oracle, SQL Server).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a view passing on information from a database: def serve_article(request, id): served_article
Let's say I'm outputting a post title and in our database, it's Hello Y’all
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
For some reason, after submitting a string like this Jack’s Spindle from a text
I'm interested in microtypography issues on the web. I want a tool to fix:
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
I've tracked down a weird MySQL problem to the two different ways I was
I have a text area in my form which accepts all possible characters from
I'm trying to convert HTML to plain text. I get many &\#8217; &\#8220; etc.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.