Debería leer lo siguiente y aprender un poco sobre las ventajas de una tabla innodb bien diseñada y la mejor manera de usar índices agrupados, ¡solo disponible con innodb!
http://dev.mysql.com/doc /refman/5.0/en/innodb-index-types.html
http://www. xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/
luego diseñe su sistema algo similar al siguiente ejemplo simplificado:
Esquema de ejemplo (simplificado)
Las características importantes son que las tablas utilizan el motor innodb y la clave principal para la tabla de subprocesos ya no es una única clave de incremento automático, sino una clave agrupada compuesta. clave basada en una combinación de forum_id y thread_id. por ejemplo
threads - primary key (forum_id, thread_id)
forum_id thread_id
======== =========
1 1
1 2
1 3
1 ...
1 2058300
2 1
2 2
2 3
2 ...
2 2352141
...
Cada fila del foro incluye un contador llamado next_thread_id (int sin firmar) que se mantiene mediante un activador y aumenta cada vez que se agrega un hilo a un foro determinado. Esto también significa que podemos almacenar 4000 millones de subprocesos por foro en lugar de 4000 millones de subprocesos en total si usamos una única clave principal de incremento automático para thread_id.
forum_id title next_thread_id
======== ===== ==============
1 forum 1 2058300
2 forum 2 2352141
3 forum 3 2482805
4 forum 4 3740957
...
64 forum 64 3243097
65 forum 65 15000000 -- ooh a big one
66 forum 66 5038900
67 forum 67 4449764
...
247 forum 247 0 -- still loading data for half the forums !
248 forum 248 0
249 forum 249 0
250 forum 250 0
La desventaja de usar una clave compuesta es que ya no puede simplemente seleccionar un hilo por un solo valor de clave de la siguiente manera:
select * from threads where thread_id = y;
tienes que hacer:
select * from threads where forum_id = x and thread_id = y;
Sin embargo, el código de su aplicación debe saber en qué foro está navegando un usuario, por lo que no es exactamente difícil de implementar:almacene el forum_id que se ve actualmente en una variable de sesión o en un campo de formulario oculto, etc.
Aquí está el esquema simplificado:
drop table if exists forums;
create table forums
(
forum_id smallint unsigned not null auto_increment primary key,
title varchar(255) unique not null,
next_thread_id int unsigned not null default 0 -- count of threads in each forum
)engine=innodb;
drop table if exists threads;
create table threads
(
forum_id smallint unsigned not null,
thread_id int unsigned not null default 0,
reply_count int unsigned not null default 0,
hash char(32) not null,
created_date datetime not null,
primary key (forum_id, thread_id, reply_count) -- composite clustered index
)engine=innodb;
delimiter #
create trigger threads_before_ins_trig before insert on threads
for each row
begin
declare v_id int unsigned default 0;
select next_thread_id + 1 into v_id from forums where forum_id = new.forum_id;
set new.thread_id = v_id;
update forums set next_thread_id = v_id where forum_id = new.forum_id;
end#
delimiter ;
Es posible que haya notado que he incluido answer_count como parte de la clave principal, lo cual es un poco extraño ya que el compuesto (forum_id, thread_id) es único en sí mismo. Esta es solo una optimización de índice que ahorra algunas operaciones de E/S cuando se ejecutan consultas que usan answer_count. Consulte los 2 enlaces anteriores para obtener más información al respecto.
Consultas de ejemplo
Todavía estoy cargando datos en mis tablas de ejemplo y hasta ahora tengo cargado aprox. 500 millones de filas (la mitad que su sistema). Cuando se complete el proceso de carga, debo esperar tener aproximadamente:
250 forums * 5 million threads = 1250 000 000 (1.2 billion rows)
He hecho deliberadamente que algunos de los foros contengan más de 5 millones de hilos, por ejemplo, el foro 65 tiene 15 millones de hilos:
forum_id title next_thread_id
======== ===== ==============
65 forum 65 15000000 -- ooh a big one
Tiempos de ejecución de consultas
select sum(next_thread_id) from forums;
sum(next_thread_id)
===================
539,155,433 (500 million threads so far and still growing...)
en innodb, sumar next_thread_ids para obtener un recuento total de subprocesos es mucho más rápido que lo habitual:
select count(*) from threads;
Cuántos hilos tiene el foro 65:
select next_thread_id from forums where forum_id = 65
next_thread_id
==============
15,000,000 (15 million)
de nuevo, esto es más rápido que lo habitual:
select count(*) from threads where forum_id = 65
Bien, ahora sabemos que tenemos alrededor de 500 millones de subprocesos hasta el momento y el foro 65 tiene 15 millones de subprocesos. Veamos cómo funciona el esquema :)
select forum_id, thread_id from threads where forum_id = 65 and reply_count > 64 order by thread_id desc limit 32;
runtime = 0.022 secs
select forum_id, thread_id from threads where forum_id = 65 and reply_count > 1 order by thread_id desc limit 10000, 100;
runtime = 0.027 secs
Me parece bastante eficaz, así que es una sola tabla con más de 500 millones de filas (y creciendo) con una consulta que cubre 15 millones de filas en 0,02 segundos (¡mientras está bajo carga!)
Otras optimizaciones
Estos incluirían:
-
partición por rango
-
fragmentación
-
tirarle dinero y hardware
etc...
espero que encuentres esta respuesta útil :)