-1

I got this table(made up but similar )

Items (ot_id,numval1,numval2)

And I do a query like this:

Select from OtherTable ot JOIN Items on ot.id=Items.ot_id where 
Items.numval1 > 1 and Items.numval2 < 300

Now when i create the compound index on Items to cover above query can I do:

create index  idx1 on Items (ot_id,numval1,numval2);

Is the order correct ? Do I need the ot_id in there ?

3
  • Is the order correct ? Depends by the percent of records mathed the conditions by numvalN fields. Maybe those fields must be switched. In any case it is covering index, so removing any field from seems to be not safe (excluding the variant this index is not safe at all).
    – Akina
    Commented Oct 16, 2018 at 10:13
  • I dont follow the statement "excluding the variant this index is not safe at all" ?
    – koosme
    Commented Oct 16, 2018 at 13:13
  • For example if total selectivity of all 3 conditions is 50% the table scan may be more effective. Or at least not less effective. In that case the index is a disk space waste, and data alter performance decreaser.
    – Akina
    Commented Oct 16, 2018 at 13:40

1 Answer 1

0

Case 1 (This is not your case, but bear with me)

FROM Items
    where  ot_id = 321
      and  numval1 > 1
      and  numval2 < 300 

Have two indexes:

INDEX(ot_id, numval1)
INDEX(ot_id, numval2)

od_id is first because it is tested with =. Once a range (eg, numval1 > 1) is hit, no further columns in the index can be used.

The Optimizer will pick between them based on which range test (numval1 or numval2) might be faster. The Optimizer cannot use the 3-column index you suggested. (Or, rather, it will not use the third column.)

You have not said what values you will be SELECTing. If it is no more than those 3 columns, then a "covering" index will be a slight benefit:

INDEX(ot_id, numval1, numval2)
INDEX(ot_id, numval2, numval1)

Again, this leaves it to the Optimizer to dynamically decide which is better.

As Akina points out, the Optimizer could screw up and fail to notice that a table scan would be better.

Case 2 (The query as you have it)

     from  OtherTable ot
     JOIN  Items  ON ot.id=Items.ot_id
    where  Items.numval1 > 1
      and  Items.numval2 < 300 

Notice that the WHERE clause talks only about Items. So, it is extremely likely that the Optimizer will start with it, then JOIN to OtherTable. Again it leads to 2 choices:

INDEX(numval1)
INDEX(numval2)

Or, if covering:

INDEX(numval1, numval2, ot_id)
INDEX(numval2, numval1, ot_id)

(The last pair of columns can be in either order.)

Then, to get to ot, there needs to be an index on id, presumably, you have PRIMARY KEY(id)?

(So, I disagree with Akina's answers.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.