sql >> Databasteknik >  >> RDS >> Mysql

Hur man korrekt indexerar en länkningstabell för många-till-många-anslutning i MySQL?

Det beror på hur du söker.

Om du söker så här:

/* 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

då behöver du:

ALTER TABLE table_table ADD CONSTRAINT pk_table1_table2 (table_1, table_2)

I det här fallet, table1 kommer att leda i NESTED LOOPS och ditt index kan endast användas när table1 indexeras först.

Om du söker så här:

/* 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

då behöver du:

ALTER TABLE table_table ADD CONSTRAINT pk_table1_table2 (table_2, table_1)

av skälen ovan.

Du behöver inga oberoende index här. Ett sammansatt index kan användas överallt där ett vanligt index på den första kolumnen kan användas. Om du använder oberoende index kommer du inte att kunna söka effektivt efter båda värdena:

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

För en fråga som denna behöver du minst ett index på båda kolumnerna.

Det är aldrig dåligt att ha ett extra index för det andra fältet:

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

Primär nyckel kommer att användas för sökningar on both values och för sökningar baserade på värdet för table_1 , kommer ytterligare index att användas för sökningar baserat på värdet table_2 .



  1. Ogiltig parametertyp (numpy.int64) vid infogning av rader med executemany()

  2. GPL och libmysqlclient

  3. Oracle:hur lägger man till minuter till en tidsstämpel?

  4. Ändra precisionen för numerisk kolumn i Oracle