简体   繁体   中英

Proper indexing for an InnoDB table

I have an InnoDB table with the following columns

  • id MEDIUMINT UNSIGNED AUTO_INCREMENT
  • a VARBINARY(16)
  • b CHAR(2)
  • c VARCHAR(100)
  • d MEDIUMINT UNSIGNED
  • e TINYINT UNSIGNED, range 0-49

I'll be performing such a query most of the time

SELECT d, e, c FROM tbl WHERE a=0x5caffbb2 AND d>1000000 AND (e=1 OR e=5 OR e=6 OR e=8 OR e=15)

How should I set up indexes for

  1. maximum SELECT speed
  2. decent SELECT speed and high INSERT speed

For the select:

INDEX(a, d)

First column(s), namely a , in index should be compared "= constant".

Then comes one range, namely d > ... .

The other stuff is hard to index because of OR . However, it is all the same variable: e=1 OR e=5 OR e=6 OR e=8 OR e=15 , which is equivalent to e IN (1, 5, 6, 8, 15) . So, this is better:

INDEX(a, e, d)

This is because the optimizer (in 5.6) can "leapfrog" through the index for e . That is, after all the '=' columns, and before the one 'range', you have one 'IN'.

This is a "covering" index:

INDEX(a, e, d, c)

It may be even better. There is a tradeoff between the bulkiness and the "covering". It is not easy to predict whether it will be better; furthermore it may be better for some values and worse for others. This will be 320 bytes versus 20.

(Note: the columns in this index, and the others, must be in the order given.)

more .

For the INSERT

LOAD DATA is probably the best. However if the number of rows in the LOAD are too many, it may have an adverse impact on the SELECTs . Also very good is batched INSERTs of 100-1000 rows per batch.

VARBINARY

That is probably a packed MD5 or IPv6? It may as well be BINARY(16) ? It does not hurt the indexing as much as some people say.

InnoDB

Of course, use InnoDB, not MyISAM.

Achieve maximum select speed via composites or covered indexes. Problem is, your varchars will get in the way. They (at least one at the moment) are too wide for covered, but your ints are not. So consider choosing a composite index in the most frequently used fashion such as

key (i1,i2,i2) 

for some ints.

For maximum insert speed, choose LOAD DATA INFILE , the hands down fastest approach, even in cases of interactive GUI apps. It takes some configuration of worktables to bring in data. You will need to juggle concepts such as whether or not the data previously existed. And often craft special update with a join pattern solutions for getting the data into the real table from the work table. The fact of the matter is that no looping with binding will achieve this throughput.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM