sql >> Base de Datos >  >> RDS >> Mysql

Consejos necesarios para indexar correctamente una tabla con muchos campos en los que buscar

Tengo una mesa en el trabajo con el mismo tipo de cosas, muchas columnas y 1000 formas diferentes de seleccionar. Es una pesadilla. Sin embargo, encontré que hay ciertas combinaciones de filtros que se usan con frecuencia. Son aquellos para los que crearía índices y dejaría a los otros que rara vez se utilizan para ejecutarse lentamente. En MSSQL, puedo ejecutar una consulta para mostrarme las consultas más caras que se han ejecutado en la base de datos, mySQL debería tener algo similar. Una vez que las tengo, creo un índice que cubre las columnas para acelerarlas. Eventualmente, lo tendrás cubierto en un 90 por ciento. Personalmente, nunca volvería a diseñar una mesa como esa a menos que tuviera un AK47 apuntándome. (Mis índices son 3 veces más grandes que los datos en la tabla, lo cual no es genial si necesita agregar un montón o registros). Sin embargo, no estoy seguro de cómo rediseñaría la tabla. Mi primer pensamiento sería dividir la tabla en dos , pero eso se sumaría a los dolores de cabeza en otros lugares.

Tabla de usuarios (ID de usuario, nombre)

1, Lisa
2, Jane
3, John

Tabla de atributos de usuario (ID de usuario, nombre de atributo, valor de atributo)

1, EYES, Brown
1, GENDER, Female
2, EYES, Blue
2, GENDER, Female
3  EYES, Blue
3, GENDER, Male

Esto haría que la identificación de atributos fuera más rápida, pero sus consultas no serían tan sencillas de escribir.

SELECT UserID, COUNT(*) as MatchingAttributes
FROM   UserAttributes 
WHERE  (UserAttributes.AttributeName = 'EYES' AND UserAttributes.AttributeValue = 'Blue') OR
       (UserAttributes.AttributeName = 'GENDER' AND UserAttributes.AttributeValue = 'Female') 

Esto debería devolver lo siguiente

UserID, MatchingAttributes
1, 1
2, 2
3, 1

Todo lo que necesita hacer entonces es agregar HAVING COUNT (*) =2 a la consulta para seleccionar solo las ID que coinciden. Es un poco más complicado para seleccionar, pero también ofrece una característica interesante, digamos que filtra en 10 atributos y devuelve todos aquellos que tienen 10 coincidencias. Genial, pero digamos que ninguno coincidió al 100%. Podrías decir oye, no encontré ninguno que coincidiera, pero estos tenían 9 de 10 o un 90% de coincidencia. (solo asegúrese de que, si busco una mujer rubia de ojos azules, no recibo un mensaje que diga que no se encontró ninguna, pero aquí están las siguientes coincidencias más cercanas que contienen tipos rubios de ojos azules con un puntaje coincidente de 60 %. Eso sería ser muy poco cool)

Hay más cosas que deberían tenerse en cuenta si elige dividir la tabla, por ejemplo, ¿cómo almacena atributos como números, fechas y texto en una sola columna? ¿O son estas tablas o columnas separadas? No hay una respuesta fácil, ya sea mesa ancha o mesas divididas.