views:

22

answers:

1

Hello,

I was wondering if somebody knows an elegant solution to the following:

Suppose I have a table that holds orders, with a bunch of data. So I'm at 1M records, and searches begin to take time. So I want to speed it up by archiving some data that is more than 3 years old - saving it into a table called orders-archive, and then purging them from the orders table. So if we need to research something or customer wants to pull older information - they still can, but 99% of the lookups are done on the orders no older than a year and a half - so there is no reason to keep looking through older data all the time. These move & purge operations can be then croned to be done on a weekly basis. I already did some tests and I know that I will slash my search times by about 4 times. So far so good, right?

However I was thinking about how to implement older archival lookups and the only reasonable thing I can think of is some sort of if-else If not found in orders, do a search in orders-archive. However - I have about 20 tables that I want to archive and god knows how many searches / finds are done through out the code, that I don't want to modify. So I was wondering if there is an elegant rails-way solution to this problem, by extending a model somehow? Has anyone dealt with similar case before?

Thank you.

+1  A: 

MySQL 5.x can handle this natively using Horizontal Partitioning.

The basic idea behind partitioning is that you tell the database to store records in a certain range in a separate file. You can still query against all the records, but as long as you're querying only current records, the database engine won't be encumbered with all of the archived records.

You can use the order_date column or something similar as the cutoff for your partitions. This is the elegant solution.

Overview of Partitioning in MySQL

Otherwise, your if/else idea with dynamically generated queries seems about right. You can add year numbers after the archival tables and use reflection to build a list of tables, then have at it.

Marcus Adams
Marcus, thank you - I've used my approach before long time ago with a php and perl, because partitioning wasn't supported by mysql. I haven't realized that mysql added partitioning support. However our current app is using mysql 5.0.32 on Debian Sarge (5.1 wasn't available at the time), nothing is stopping us from upgrading except for the lack of time :-(. So I guess I'll have to see what we can do about upgrading. I'll wait to see if anybody else has a rails-based solution different from mine, which would let us postpone upgrade.
Nick Gorbikoff
BTW, is partitioning transparent to the Rails's model? What I mean is let's say I need to modify my model (add payment_method field, that is set to not NULL, and has no default), do I need my migrations to do something special to accommodate for the underlying table? Or would I need to maintain all partitions manually directly though mysql?
Nick Gorbikoff
@Nick, Sorry, I don't know enough about the implementation details of Rails migrations to answer that question.
Marcus Adams
@Marcus, sorry if I wasn't clear: I was asking more in terms of implementation on mysql side - is partitioned file transparent to the whatever client connects to it or does it appear as a separate table? So that when I write a select * from order where date = "2002-10-15" (which would be the archived data set) or alter table statement , do I need to tell mysql something else regarding this table?
Nick Gorbikoff
@Nick, It would be transparent to any application. Rails would not have to know about it or do anything special.
Marcus Adams
@Marcus, thank you!!!
Nick Gorbikoff