Ver Mensaje Individual
  #1 (permalink)  
Antiguo 20/07/2015, 06:46
Avatar de manuparquegiralda
manuparquegiralda
 
Fecha de Ingreso: junio-2012
Ubicación: Barcelona
Mensajes: 241
Antigüedad: 12 años, 5 meses
Puntos: 39
Optimizar consulta para aprovechar indices

Buenas tardes a todos.

Verán, tengo un problema con una tabla muy sencillita en la que se almacenan contactos del tipo si somos amigos o no. Es decir en la web puedes añadir a un usuario como amigo y si este acepta pues en la tabla de contactos se almacenan los id de los usuarios que se hicieron amigos y la fecha.

El tema está en que esta tabla empieza a tener muchos valores y cuando hago consultas se relentizan demasiado ya que los índices que tengo creados no se utilizan.

La tabla sería algo así:

Table contactos ->
id -> INT PRIMARY
contacto_1 -> INT
contacto_2 -> INT
fecha -> DATETIME

Entonces suponiendo que yo soy un usuario con el ID 1 y agrego a un usuario con el ID 48, se almacenaría en el campo contacto_1 el ID 1 y en el campo contacto_2 el ID 48. Pero supongamos que el usuario con ID 48 agrega como amigo el usuario con ID 96. En este caso se almacena en el campo contacto_1 el ID 48 y en el campo contacto_2 el ID 96.

Hasta aquí todo es sencillo, pero claro, cuando quiero obtener los amigos del ID 48, la consulta debo hacerla así:

Código MySQL:
Ver original
  1. SELECT * FROM contactos WHERE contacto_1 = '48' OR contacto_2 = '48'

Esto se da a que el ID 48 puede estar en cualquiera de los campos contacto_1 o contacto_2, pero claro con esta consulta donde en lugar de preguntar con un AND pregunto con un OR no consigo que me aproveche ningún indice, al menos, de los que se me ocurre crear.

He creado para probar cuatro índices uno simple para el campo contacto_1, otro simple para contacto_2 otro compuesto para ambos campos, poniendo primero contacto_1 y seguido contacto_2 y otro combinado para ambos campos pero modificando el orden, contacto_2 y contacto_1.

Con esa consulta que es la única que he conseguido que me arroje todos los resultados donde el ID 48 esté en uno u otro campo, después de hacerle un EXPLAIN a la consulta, me dice que no aprovecha ningún índice y me hace un recorrido completo de la tabla. He probado también con el FORCE INDEX, pero no hay manera no usa ninguno. Y he probado a cambiar la consulta usando INNER JOIN o subselects, pero en este caso si he conseguido usar os índices pero no he conseguido que me arroje todos los resultados.

¿A alguien se le ocurre como podría hacer? ¿Sería mejor guardar cada amistad por duplicado en ambos órdenes de manera que cuando busque el ID 48 siempre se encuentre en el campo contacto_1 para usar un índice simple en el campo? ¿O seria mejor rehacer la tabla completamente planteándola de otra manera?

Muchas gracias a todos.
__________________
Diseño Web - Arisman Web