Si tienes una tabla con varios millones de registros y sabes de antemano que se va a consultar por periodos mensuales, puedes particionar la tabla por años y meses. Así cuando hagas consultas, sólo utilizarás la partición correspondiente y mejorará el rendimiento.
Al particionar por los valores de un determinado campo, es obligatorio tener dicho campo como parte de la primary key de la tabla.
A continuación una migración para crear una tabla particionada por meses y años:
class CreateHistoryAlerts < ActiveRecord::Migration
FIRST_YEAR = 2010
LAST_YEAR = 2020
def self.up
create_table :history_alerts do |t|
t.integer :agent_id, :references => nil
t.integer :alert_type_id, :references => nil
t.integer :country_id, :references => nil
t.string :reason
t.boolean :read
t.timestamps
end
sql = "ALTER TABLE `history_alerts` drop primary key, add primary key(id, created_at)"
execute(sql);
sql = "ALTER TABLE `history_alerts` PARTITION BY RANGE (YEAR(created_at)) \
SUBPARTITION BY HASH (MONTH(created_at)) \
("
for year in (FIRST_YEAR..LAST_YEAR)
sql += "PARTITION p_#{year} VALUES LESS THAN (#{year}) \
(SUBPARTITION s_jan_#{year}, \
SUBPARTITION s_feb_#{year}, \
SUBPARTITION s_mar_#{year}, \
SUBPARTITION s_apr_#{year}, \
SUBPARTITION s_may_#{year}, \
SUBPARTITION s_jun_#{year}, \
SUBPARTITION s_jul_#{year}, \
SUBPARTITION s_aug_#{year}, \
SUBPARTITION s_sep_#{year}, \
SUBPARTITION s_oct_#{year}, \
SUBPARTITION s_nov_#{year}, \
SUBPARTITION s_dec_#{year}),"
end
sql += "PARTITION p_all VALUES LESS THAN MAXVALUE \
(SUBPARTITION s_jan_all, \
SUBPARTITION s_feb_all, \
SUBPARTITION s_mar_all, \
SUBPARTITION s_apr_all, \
SUBPARTITION s_may_all, \
SUBPARTITION s_jun_all, \
SUBPARTITION s_jul_all, \
SUBPARTITION s_aug_all, \
SUBPARTITION s_sep_all, \
SUBPARTITION s_oct_all, \
SUBPARTITION s_nov_all, \
SUBPARTITION s_dec_all))"
execute(sql);
end
def self.down
drop_table :history_alerts
end
end
martes, 30 de noviembre de 2010
Suscribirse a:
Entradas (Atom)