tags:

views:

130

answers:

6

I have a table with columns like this:

| Country.Number | CountryName |
| US.01          | USA     |
| US.02          | USA     |

I'd like to modify this to:

| Country | Number | CountryName |
| US      | 01     | USA     |
| US      | 02     | USA     |

Regarding optimization, is there a difference in performance if I use:

select * from mytable where country.number like "US.%"

or

select * from mytable where country = "US"
+4  A: 

The later query:

select * from mytable where country = "US"

should be much faster because mySQL does not have to look for wildcards patterns unlike LIKE query. It just looks for the value that has been equalized.

Sarfraz
I believe you're wrong. It does not look for patterns, but uses the index for the first three characters and immediately displays the result. That may be faster than ` = "US"` but not *much*.
Raveren
Just running manual queries I got some pretty anomalous results. On the first pair of queries, `=` took _17.49s_ vs. 19.18s for `like`. On the second run, it was 3.20s vs. _0.42s_. And on the 3rd run, _0.39s_ vs. 0.42s. On each run after that both queries took either 0.41s or 0.39s to execute, with no advantage to either queries after 10 additional sets of queries. I'm guessing you'll need to use a profiler like Piskvor suggests to get more definitive results. But this is probably unnecessary micro-optimization in most cases.
Lèse majesté
Use `SELECT sql_no_cache ...`. Anyway, `17.49s vs. 19.18s` is indeed miniscule.
Raveren
+2  A: 

The second is faster if there is an index on column country. MySQL has to scan less index entries to produce the result.

Eduardo Mauro
+3  A: 

If you need to optimize, a simple = is way better than a like.

Why ?

  • With an = either the string is exactly the same and it's true or it doesn't match and it's false.
  • With a like, MySQL must compare the string and test if the other string match the mask, and that takes more time and needs more operations.

So for the sake of your database, use select * from mytable where country = "US".

Colin Hebert
+5  A: 

Still, the performance difference may be miniscule, as mysql uses an index on "US.%". The performance degradation is mostly felt when searching for something like "%.US" (the wildcard is in front). As it then does a tablescan without using indices.

EDIT: you can look at it like this:

Mysql internally stores varchar indices like trees with first symbol being the root and branching to each next letter.

So when searching for = "US" it looks for U, then goes one down step for S and then another to make sure that is the end of the value. That's three steps.

Searching for LIKE "US.%" it looks again for U, then S, then . and then stops searching and displays the results - thats also three steps only as it cares not whether the value terminated there.

EDIT2: I'm in no way promoting such database denormalization, I just wanted to attract your attention that this matter may not be as straightforward as it seems at first glance.

Raveren
+1  A: 

Not technically an answer to the question.. but...I would understand them to be close enough in speed for it not to (usually) matter - thus using "=" would be better as it displays the intent in a more obvious way.

tim
A: 

why dont you just make country_id a tinyint unsigned and have an iso_code varchar(3) column which is unique ? (saves you from all the BS)

f00