tags:

views:

45

answers:

1

I have a MyISAM table containing ~20 million rows, and need to increase the maximum size of a varchar. No matter how I phrase the ALTER TABLE query, it takes forever as MySQL copies all the data to a temporary table, reindexes it, etc - it seems to think that the data needs to be converted. Since it's a varchar already, I'd have thought it wouldn't need to do any of this.

Is there some way to force MySQL to increase the maximum length of a varchar without going through this horribly slow and painful process? I'm ideally looking for something which can be done entirely using SQL, so no trickery involving copying .frm files around etc.

+1  A: 

One alternative would be to

  1. create a copy of the table, but with the increased VARCHAR you need the table to be. BUT NO INDEXES.
  2. Populate the new version of the table:

    INSERT INTO new_table
    SELECT * FROM old_table
    
  3. Apply indexes
  4. Update application references to use new_table

Step 4 can be minimized by updating the application to use a view that points to old_table until the new_table is ready. Then you refresh the view, setting it to use new_table...

OMG Ponies
Selecting into a new table and then indexing it would still take a long time, though - I'm after a solution which results in the change happening very quickly (to my mind, there's no reason why it can't just update the table definition, since varchars only take as much storage as needed anyway).
NullColaShip
@NullColaShip: At ~20 million rows, nothing is going to be instantaneous. You're still going to hid the IO wall; your hard drive setup is the limiting factor.
OMG Ponies
I absolutely understand that actually manipulating the rows is going to take time. My question was whether it can be done without manipulating the rows - I've seen suggestions that you can do some trickery involving replacing the .FRM file with a new one, which updates the table definition but doesn't touch the data, so I was wondering if it's at all possible to achieve that with SQL (so it can be done easily/safely from a PHP script)...
NullColaShip
+1 I wouldn't mess with the internals of mysql like that, it may work it may not, it might have worked once. it may have unintended side effects down the track. OMG Ponies answer allows the indexes to be updated just once when they as are created instead of on every insert. so it will be MUCH quicker. but still not instant.
DeveloperChris
I guess there's no way to do what I wanted, so I'll accept this answer as it's the closest that seems to be possible. It's still not going to work for me, unfortunately - but thanks anyway.
NullColaShip
@NullColaShip: Understood, thanks, and good luck.
OMG Ponies