Mysql
 sql >> Database >  >> RDS >> Mysql

Come indicizzare correttamente una tabella di collegamento per la connessione molti-a-molti in MySQL?

Dipende da come cerchi.

Se cerchi in questo modo:

/* Given a value from table1, find all related values from table2 */
SELECT *
FROM table1 t1
JOIN table_table tt ON (tt.table_1 = t1.id)
JOIN table2 t2 ON (t2.id = tt.table_2)
WHERE t1.id = @id

allora hai bisogno di:

ALTER TABLE table_table ADD CONSTRAINT pk_table1_table2 (table_1, table_2)

In questo caso, table1 sarà all'avanguardia in NESTED LOOPS e il tuo indice sarà utilizzabile solo quando table1 viene indicizzato per primo.

Se cerchi in questo modo:

/* Given a value from table2, find all related values from table1 */
SELECT *
FROM table2 t2
JOIN table_table tt ON (tt.table_2 = t2.id)
JOIN table1 t1 ON (t1.id = tt.table_1)
WHERE t2.id = @id

allora hai bisogno di:

ALTER TABLE table_table ADD CONSTRAINT pk_table1_table2 (table_2, table_1)

per i motivi di cui sopra.

Non hai bisogno di indici indipendenti qui. Un indice composito può essere utilizzato ovunque sia possibile utilizzare un indice semplice sulla prima colonna. Se utilizzi indici indipendenti, non sarai in grado di cercare in modo efficiente entrambi i valori:

/* Check if relationship exists between two given values */
SELECT 1
FROM table_table
WHERE table_1 = @id1
  AND table_2 = @id2

Per una query come questa, avrai bisogno di almeno un indice su entrambe le colonne.

Non è mai male avere un indice aggiuntivo per il secondo campo:

ALTER TABLE table_table ADD CONSTRAINT pk_table1_table2 PRIMARY KEY (table_1, table_2)
CREATE INDEX ix_table2 ON table_table (table_2)

La chiave primaria verrà utilizzata per le ricerche on both values e per ricerche basate sul valore di table_1 , verrà utilizzato un indice aggiuntivo per le ricerche basate sul valore di table_2 .