Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is MySql composite index hit for this sql?

Tags:

I have one table: student_homework, and one of its composite index is uk_sid_lsnid_version(student_id, lesson_id, curriculum_version, type):

student_homework    0   uk_sid_lsnid_version    1   student_id  A   100             BTREE       
student_homework    0   uk_sid_lsnid_version    2   lesson_id   A   100             BTREE       
student_homework    0   uk_sid_lsnid_version    3   curriculum_version  A   100             BTREE       
student_homework    0   uk_sid_lsnid_version    4   type    A   100             BTREE   

Now i have a Sql: select * from student_homework where student_id=100 and type=1 and explain result is like:

1   SIMPLE  student_homework        ref uk_sid_lsnid_version,idx_student_id_update_time uk_sid_lsnid_version    4   const   20  10.0    Using index condition

The execution plan is uk_sid_lsnid_version.

The question for me is how the query condition type works here? Does DB engine scans all (narrowed) records for it? In my understanding, the tree hierarchy architecture is:

              student_id 
               /       \
           lesson_id     lesson_id
            /                      \  
     curriculum_version          curriculum_version
       /            \
      type         type

For the query condition (student_id, type), student_id matches the root of the tree index. Yet, the type does not match index lesson_id, the DB engine would apply type on all records, which have been filted by student_id.

  1. Is my understanding is correct? if the subset records with a student_id is large, the query cost is still expensive.
  2. There is no difference between query condition student_id = 100 and type =0 and type=0 and student_id = 100
  3. To make full usage of composite index, would it be better if I add a new composite index (student_id, type)?
like image 373
shijie xu Avatar asked Aug 23 '20 12:08

shijie xu


People also ask

How does MySQL calculate composite index?

CREATE TABLE table_name ( c1 data_type PRIMARY KEY, c2 data_type, c3 data_type, c4 data_type, INDEX index_name (c2,c3,c4) ); In the above statement, the composite index consists of three columns c2, c3, and c4.

When should you use composite index?

If composite columns needs to be unique, then use composite index and set it to be unique. A composite index will also be faster if one of the column has many duplicate rows. However, composite index will only be used when both columns are included in a query.

What is composite index used for?

A composite index is a statistical tool that groups together many different equities, securities, or indexes in order to create a representation of overall market or sector performance. Composite indexes are used to conduct investment analyses, measure economic trends, and forecast market activity.


1 Answers

Yes, your understanding is correct, mysql will use uk_sid_lsnid_version index to match on student_id only, while filtering on type will be done a on the reduced set of rows that match on student_id.

The hint is in the extra column of the explain result: Using index condition

Using index condition (JSON property: using_index_condition)

Tables are read by accessing index tuples and testing them first to determine whether to read full table rows. In this way, index information is used to defer (“push down”) reading full table rows unless it is necessary. See Section 8.2.1.6, “Index Condition Pushdown Optimization”.

Section 8.2.1.6, “Index Condition Pushdown Optimization describes the steps of this technique as:

  1. Get the next row's index tuple (but not the full table row).
  2. Test the part of the WHERE condition that applies to this table and can be checked using only index columns. If the condition is not satisfied, proceed to the index tuple for the next row.
  3. If the condition is satisfied, use the index tuple to locate and read the full table row.
  4. Test the remaining part of the WHERE condition that applies to this table. Accept or reject the row based on the test result.

Whether it would be better to add another composite index on student_id, type is a question that cannot be objectively answered by us, you need to test it.

If the speed of the query with the current index is fine, then you probably do not need a new index. You also need to weigh in how many other queries would use that index - there is not much point to create an index just for one query. You also need to weigh in how selective the type field is. Type fields with a limited list of values are often not selective enough. Mysql may decide to use index condition pushdown since student_id, type index is a not a covering index and mysql would have to get the full row anyway.

like image 72
Shadow Avatar answered Oct 20 '22 06:10

Shadow