sql >> Base de Datos >  >> RDS >> PostgreSQL

Tabla de muchos a muchos:el rendimiento es malo

Lo más importante es que necesita un índice en playersinclubs(club_id, player_id) . El resto son detalles (que aún pueden marcar una gran diferencia).
Debe ser preciso acerca de sus objetivos reales. Tu escribes:

No necesitas unirte al club para esto en absoluto:

SELECT p.* 
FROM   playersinclubs pc
JOIN   player         p ON p.id = pc.player_id
WHERE  pc.club_id = 3;

Y no necesitas columnas playersinclubs en la salida, lo que es una pequeña ganancia para el rendimiento, a menos que permita un solo índice escanear en playersinclubs , entonces puede ser sustancial.

Probablemente no necesites todos columnas de player en el resultado, tampoco. Solo SELECT las columnas que realmente necesita.

El PK en player proporciona el índice que necesita en esa tabla.

Necesitas un índice en playersinclubs(club_id, player_id) , pero no hágalo único a menos que los jugadores no puedan unirse al mismo club por segunda vez.

Si los jugadores pueden unirse varias veces y solo desea una lista de "todos los jugadores", también debe agregar un DISTINCT paso para doblar entradas duplicadas. Podrías simplemente:

SELECT DISTINCT p.* ...

Pero dado que está tratando de optimizar el rendimiento:es más barato eliminar los duplicados antes:

SELECT p.*
FROM  (
   SELECT DISTINCT player_id
   FROM   playersinclubs
   WHERE  club_id = 3;
   ) pc
JOIN   player p ON p.id = pc.player_id;

Tal vez realmente quieras todo entradas en playersinclubs y todas las columnas de la tabla, también. Pero tu descripción dice lo contrario. La consulta y los índices serían diferentes.

Respuesta estrechamente relacionada: