Mysql
 sql >> база данни >  >> RDS >> Mysql

Стойности, разделени със запетая, в MySQL IN клауза

Въз основа на примера FIND_IN_SET() от @Jeremy Smith, можете да го направите с присъединяване, така че да не се налага да изпълнявате подзаявка.

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

Известно е, че това се представя много лошо, тъй като трябва да извършва сканиране на таблици, оценявайки функцията FIND_IN_SET() за всеки комбинация от редове в table и locations . Той не може да използва индекс и няма начин да го подобри.

Знам, че казахте, че се опитвате да направите най-доброто от лошия дизайн на база данни, но трябва да разберете колко драстично лошо е това.

Обяснение:Да предположим, че трябва да ви помоля да потърсите всички в телефонния указател, чийто първи, среден или последен инициал е "J." Няма начин сортираният ред на книгата да помогне в този случай, тъй като така или иначе трябва да сканирате всяка отделна страница.

LIKE Решението, дадено от @fthiella, има подобен проблем по отношение на производителността. Не може да се индексира.

Вижте също моя отговор на Толкова ли лошо ли е съхраняването на разделен списък в колона на база данни? за други капани на този начин на съхранение на денормализирани данни.

Ако можете да създадете допълнителна таблица за съхраняване на индекс, можете да картографирате местоположенията към всеки запис в списъка с градове:

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

Ако приемем, че имате справочна таблица за всички възможни градове (не само тези, споменати в table ) можете да понесете неефективността еднократно, за да създадете съпоставянето:

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;

Сега можете да изпълните много по-ефективна заявка за намиране на записи във вашата table :

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

Това може да използва индекс. Сега просто трябва да се погрижите всяко INSERT/UPDATE/DELETE на редове в locations също така вмъква съответните редове за картографиране в location2city .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на фрагменти на Oracle JDeveloper с MySQL

  2. Как да форматирате датата и часа в MySQL

  3. Как да намерите и замените текст в таблицата на mysql

  4. Обявяване на ClusterControl 1.7.2:Подобрено архивиране и поддръжка на PostgreSQL за TimescaleDB и MySQL 8.0

  5. Променете MySQL колона, за да бъде AUTO_INCREMENT