2010-11-11 28 views
6

Esta es probablemente una situación común, pero no pude encontrar una respuesta específica en SO o Google.Mantener una tabla grande de valores únicos en MySQL

Tengo una gran tabla (> 10 millones de filas) de relaciones de amistad en una base de datos MySQL que es muy importante y debe mantenerse de modo que no haya filas duplicadas. La tabla almacena los uids del usuario. El SQL para la tabla es:

CREATE TABLE possiblefriends(
id INT NOT NULL AUTO_INCREMENT, 
PRIMARY KEY(id), 
user INT, 
possiblefriend INT) 

La forma de la mesa funciona es que cada usuario tiene alrededor de 1000 más o menos "posibles amigos" que se descubren y necesitan ser almacenados, pero duplicado "posibles amigos" tienen que ser evitado

El problema es que, debido al diseño del programa, en el transcurso de un día, necesito agregar 1 millón de filas o más a la tabla que pueden ser o no entradas de fila duplicadas. La respuesta simple parecería ser comprobar cada fila para ver si es un duplicado, y si no, luego insertarlo en la tabla. Pero esta técnica probablemente será muy lenta a medida que el tamaño de la tabla aumente a 100 millones de filas, mil millones de filas o más (lo que espero que ocurra pronto).

¿Cuál es la mejor forma (es decir, la más rápida) de mantener esta tabla única?

No necesito tener una tabla con valores únicos siempre a mano. Solo lo necesito una vez al día para trabajos por lotes. En este caso, ¿debería crear una tabla separada que simplemente inserte todas las filas posibles (que contienen filas duplicadas y todas) y luego, al final del día, crear una segunda tabla que calcule todas las filas únicas en la primera tabla?

Si no, ¿cuál es la mejor manera para esta tabla a largo plazo?

(Si los índices son la mejor solución a largo plazo, por favor dígame qué índices de usar)

+0

cuestión, hace necesidad de u de consulta para la tabla 'possiblefriends'? Sólo pienso que probablemente pueda dividir la tabla según el usuario, se beneficiará cuando consulte, sin embargo, podría convertirse en un desastre de mantenimiento a largo plazo – ajreal

+0

@ajreal: ¿quiere decir que cada usuario tiene su propia tabla? habría cerca de un millón de usuarios más o menos, por lo que probablemente haría las cosas muy complicadas. – eric

+0

sí, eso es lo que mencioné que podría convertirse en un desastre de mantenimiento, ¿qué hay de usar 1k de usuario por mesa o menos? Imagine que pone todos los datos en una sola tabla, y que la mesa se cuelgue e irrecuperable, o que sea recuperable, ¿cuánto tiempo puede soportar el tiempo de inactividad? – ajreal

Respuesta

7

Agregar un índice único en (user, possiblefriend) continuación, utilice uno de:

la norma eN Asegúrese de no obtener errores cuando intente insertar una fila duplicada.

Es posible que también desee considerar si puede soltar su clave principal de incremento automático y usar (user, possiblefriend) como clave principal. Esto disminuirá el tamaño de su tabla y también la clave principal funcionará como el índice, lo que le ahorrará tener que crear un índice adicional.

Consulte también:

+1

He leído esa pregunta. ¿INSERT IGNORE or INSERT ... ON DUPLICATE KEY UPDATE es eficiente para una tabla con cientos de millones de filas en general? – eric

+1

@eric: Me imagino que 'INSERT IGNORE' es el más rápido, pero estoy adivinando. Para asegurarse de que puede ejecutar una prueba de rendimiento en los tres métodos. La respuesta más votada a la pregunta a la que me he vinculado recomienda el uso de 'INSERTAR ... EN ACTUALIZACIÓN DE LLAVE DUPLICADA'. –

+1

NB - ¡debe ser un índice único! – symcbean

2

Un índice único se lo hará estar seguro de que el campo es de hecho único, se puede añadir un índice único de este modo:

CREATE TABLE possiblefriends( 
id INT NOT NULL AUTO_INCREMENT, 
PRIMARY KEY(id), 
user INT, 
possiblefriend INT, 
PRIMARY KEY (id), 
UNIQUE INDEX DefUserID_UNIQUE (user ASC, possiblefriend ASC)) 

Esto también acelerará significativamente el acceso a su mesa.

Su otro problema con el inserto de masas es un poco más complicado, se puede utilizar el incorporado EN DUPLICADO función KEY UPDATE a continuación:

INSERT INTO table (a,b,c) VALUES (1,2,3) 
    ON DUPLICATE KEY UPDATE c=c+1; 

UPDATE table SET c=c+1 WHERE a=1; 
+0

gracias. ¿Siempre es mejor usar un índice? ¿Habría algún costo para usar un índice para tablas más grandes que debería considerar? – eric

Cuestiones relacionadas