FLX
FLX

Reputation: 2679

Mysql indexing table

I have this table :

CREATE TABLE `villes_france` (
  `code_postal` varchar(10) NOT NULL DEFAULT '',
  `code_insee` varchar(10) DEFAULT NULL,
  `ville` varchar(255) DEFAULT NULL,
  `region_rsi` varchar(2) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;

It contains 36826 rows, one for each french city. The interesting fields here are code_postal (zipcode) and ville (city).

I use it mainly for autocompletion : when something in written in one input, both input are filled.

Here is my query :

if($source == 'cp'){
    $searchSQL = "SELECT code_postal as cp, ville FROM villes_france
                  WHERE code_postal LIKE :cp LIMIT 20";
}else{
    $searchSQL = "SELECT code_postal as cp, ville FROM villes_france
                  WHERE ville LIKE :ville LIMIT 20";
}

(FYI a "%" is appended to :cp or :ville)

Neither of these field is unique (french cities can share a same zipcode) This table will be almost never updated, but a lot of select will be performed.

How would you index this table ?

I have read a lot about indexes but I would like some insight before using them for real.

Upvotes: 0

Views: 51

Answers (2)

Rick James
Rick James

Reputation: 142208

Initial choice is

INDEX(code_postal),
INDEX(ville)

One works for one query; the other for the other.

A better choice would be to provide a 'covering' index for each query:

INDEX(code_postal, ville),
INDEX(ville, code_postal)

Yet another cookbook on indexing.

Suggest you not do the lookup until the user has typed at least 2 characters; there is no use showing the first 20 out of thousands of choices.

You did not specify a COLLATION on the column/table, so you probably have latin1_swedish_ci? It may actually be best for your French application since E=e=È=É=Ê=Ë=è=é=ê=ë. (latin1_general_ci treats things as separate: E=e < È=è < É=é < Ê=ê < Ë=ë .) Of note, the swedish collation includes N=n=Ñ=ñ.

Upvotes: 1

Shadow
Shadow

Reputation: 34232

To determine what indexes to create, you should analyse all use cases, not just one.

If you are happy to optimise this lookup functionality only, then create single column index on both code_postal and ville fields. There is no point to create a composite index, since mysql can only use a composite index for a single field lookup, if that single field is the leftmost in that index.

Since this is a relatively small table, which rarely gets updated, I would not hesitate to play around with indexes. Use mysql's explain select ... command to confirm if a newly created index is indeed used by a query.

Upvotes: 0

Related Questions