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

Kommaseparerede værdier i MySQL IN-sætning

Med udgangspunkt i eksemplet FIND_IN_SET() fra @Jeremy Smith kan du gøre det med en join, så du ikke behøver at køre en underforespørgsel.

SELECT * FROM table t
JOIN locations l ON FIND_IN_SET(t.e_ID, l.city) > 0
WHERE l.e_ID = ?

Dette er kendt for at fungere meget dårligt, da det skal udføre tabelscanninger, evaluere funktionen FIND_IN_SET() for hver kombination af rækker i table og locations . Det kan ikke gøre brug af et indeks, og der er ingen måde at forbedre det på.

Jeg ved, at du sagde, at du forsøger at få det bedste ud af et dårligt databasedesign, men du må forstå, hvor drastisk det er.

Forklaring:Antag, at jeg skulle bede dig om at slå alle op i en telefonbog, hvis første, midterste eller sidste initial er "J." Der er ingen måde, den sorterede rækkefølge af bogen hjælper i dette tilfælde, da du alligevel skal scanne hver enkelt side.

LIKE løsning givet af @fthiella har et lignende problem med hensyn til ydeevne. Det kan ikke indekseres.

Se også mit svar til Er lagring af en afgrænset liste i en databasekolonne virkelig så dårlig? for andre faldgruber ved denne måde at lagre denormaliserede data på.

Hvis du kan oprette en supplerende tabel til at gemme et indeks, kan du kortlægge placeringerne til hver post i bylisten:

CREATE TABLE location2city (
 location INT,
 city INT,
 PRIMARY KEY (location, city)
); 

Forudsat at du har en opslagstabel for alle mulige byer (ikke kun dem, der er nævnt i table ) kan du bære ineffektiviteten én gang til at producere kortlægningen:

INSERT INTO location2city (location, city)
  SELECT l.e_ID, c.e_ID FROM cities c JOIN locations l
  ON FIND_IN_SET(c.e_ID, l.city) > 0;

Nu kan du køre en meget mere effektiv forespørgsel for at finde poster i din table :

SELECT * FROM location2city l
JOIN table t ON t.e_ID = l.city
WHERE l.e_ID = ?;

Dette kan gøre brug af et indeks. Nu skal du bare passe på, at enhver INDSÆT/OPDATERING/SLET af rækker på locations indsætter også de tilsvarende kortlægningsrækker i location2city .



  1. Konverter SQLITE SQL dump-fil til POSTGRESQL

  2. Højere kardinalitetskolonne først i et indeks, når det involverer et interval?

  3. Sådan arbejder du med arv i Entity Framework Core

  4. Hvordan kan jeg eksportere indholdet af en oracle-tabel til en fil?