sql >> Databasteknik >  >> RDS >> Mysql

Kommaseparerade värden i MySQL IN-satsen

Med utgångspunkt i exemplet FIND_IN_SET() från @Jeremy Smith kan du göra det med en join så att du inte behöver köra en underfråga.

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

Detta är känt för att fungera mycket dåligt, eftersom det måste göra tabellsökningar, utvärdera funktionen FIND_IN_SET() för varje kombination av rader i table och locations . Det kan inte använda ett index, och det finns inget sätt att förbättra det.

Jag vet att du sa att du försöker göra det bästa av en dålig databasdesign, men du måste förstå hur drastiskt dåligt detta är.

Förklaring:Anta att jag skulle be dig slå upp alla i en telefonbok vars första, mitten eller sista initial är "J." Det finns inget sätt att den sorterade ordningen i boken hjälper i det här fallet, eftersom du måste skanna varje sida ändå.

LIKE lösningen från @fthiella har ett liknande problem när det gäller prestanda. Det kan inte indexeras.

Se även mitt svar till Är det verkligen så dåligt att lagra en avgränsad lista i en databaskolumn? för andra fallgropar med detta sätt att lagra denormaliserade data.

Om du kan skapa en tilläggstabell för att lagra ett index, kan du mappa platserna till varje post i stadslistan:

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

Förutsatt att du har en uppslagstabell för alla möjliga städer (inte bara de som nämns i table ) kan du stå ut med ineffektiviteten en gång för att producera kartläggningen:

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öra en mycket effektivare fråga för att hitta poster i din table :

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

Detta kan använda sig av ett index. Nu behöver du bara se till att alla INFOGA/UPPDATERA/RADERA rader på locations infogar också motsvarande mappningsrader i location2city .



  1. Rätt sätt att ge användare tillgång till ytterligare scheman i Oracle

  2. Varför avrundar SQL Server resultaten av att dividera två heltal?

  3. Kontrollera om RPC Out är aktiverat på en länkad server

  4. T-SQL Datetime Data Type