views:

1243

answers:

9

I have an enormous MySQL (InnoDB) database with millions of rows in the sessions table that were created by an unrelated, malfunctioning crawler running on the same server as ours. Unfortunately, I have to fix the mess now.

If I try to truncate table sessions; it seems to take an inordinately long time (upwards of 30 minutes). I don't care about the data; I just want to have the table wiped out as quickly as possible. Is there a quicker way, or will I have to just stick it out overnight?

+4  A: 

Couldn't you grab the schema drop the table and recreate it?

Nate Bross
I thought "truncate" was a synonym for "delete from". But I've checked and in recent versions it actually drops and recreates the table, yes. (Unless it is referenced in one FK or another).
shylent
That is what I thought, apparently thats not the case; however, others are also saying to use drop -- there must be some difference in the way that truncate works.
Nate Bross
Truncate will remove the rows from the table, leaving the schema intact. Drop will literally delete the table. If there's indices on sessions, that may be what's causing it to take a while. Cf. http://stackoverflow.com/questions/135653/difference-between-drop-table-and-truncate-table
sheepsimulator
What would you do if there were indices on the table?
John Feminella
If the indexes are the problem, drop them first, truncate, then recreate the indexes. But dropping the table wholesale (including temporarily dropping any foreign key references first) is likely the best solution over all.
Will Hartung
+2  A: 

Have you tried to use "drop"? I've used it on tables over 20GB and it always completes in seconds.

Zenshai
+2  A: 

drop table should be the fastest way to get rid of it.

McWafflestix
+1  A: 

If you just want to get rid of the table altogether, why not simply drop it?

shylent
+12  A: 

The quickest way is to use DROP TABLE to drop the table completely and recreate it using the same definition. If you have no foreign key constraints on the table then you should do that.

If you're using MySQL version greater than 5.0.3, this will happen automatically with a TRUNCATE. You might get some useful information out of the manual as well, it describes how a TRUNCATE works with FK constraints. http://dev.mysql.com/doc/refman/5.0/en/truncate.html

EDIT: TRUNCATE is not the same as a drop or a DELETE FROM. For those that are confused about the differences, please check the manual link above. TRUNCATE will act the same as a drop if it can (if there are no FK's), otherwise it acts like a DELETE FROM with no where clause.

womp
A: 

We had these issues. We no longer use the database as a session store with Rails 2.x and the cookie store. However, dropping the table is a decent solution. You may want to consider stopping the mysql service, temporarily disable logging, start things up in safe mode and then do your drop/create. When done, turn on your logging again.

Brian Hogan
A: 

The best way I have found of doing this with MySQL is:

DELETE from table_name LIMIT 1000;

Or 10,000 (depending on how fast it happens).

Put that in a loop until all the rows are deleted.

Please do try this as it will actually work. It will take some time, but it will work.

adnan.
I'm sorry, but if you are actually going to delete the rows, why not simply do "delete from table_name" ?
shylent
Have you done this before with a large table? "delete from ..." will usually just take up large amounts of CPU and take longer. The fewer rows there are, the faster the deletes become. Try it sometime. This is not an intellectual exercise, this actually works with MySQL.
adnan.
Also this way you can monitor the progress of the deletes.
adnan.
Well, yes. I have done 'delete from ...' on a really large dataset (think hundreds of millions) and yes it took a very long time, but that is to be expected (it also took extremely long time for the table to shrink after that). with LIMIT I just break it up into multiple deletes, but the total time will be just the same, right?..
shylent
... One thing I do NOT get though, is the part with WHERE 1=1. What purpose does it exactly serve? As far as I know, it doesn't get processed in any way, the optimizer just drops conditions like this (that can not influence the outcome of the query in any way), so the WHERE clause might've not even been here altogether. Care to clarify?Note, that I am not trying to find a mistake in your reasoning, I am just really curious, as I don't quite understand what you've meant.
shylent
You're right, the "WHERE 1=1" part is not necessary.
adnan.
+1  A: 

Truncate is fast, usually on the order of seconds or less. If it took 30 minutes, you probably had a case of some foreign keys referencing the table you were truncating. There may also be locking issues involved.

Truncate is effectively as efficient as one can empty a table, but you may have to remove the foreign key references unless you want those tables scrubbed as well.

Autocracy
+1  A: 

I'm not sure why it's taking so long. But perhaps try a rename, and recreate a blank table. Then you can drop the "extra" table without worrying how long it takes.

Brent Baisley