Як реалізується LIKE?


22

Чи може хтось пояснити, як оператор LIKE реалізується в сучасних системах баз даних (наприклад, MySQL або Postgres)? або вказати мені на деякі посилання, які пояснюють це?

Наївний підхід полягав би в тому, щоб перевірити кожен запис, виконавши регулярне вираження чи часткове збіг рядків на поле інтересу, але у мене є відчуття (сподівання), що ці системи роблять щось розумніше.

Відповіді:


19

Ні, це майже все, що вони роблять. Тепер, якщо немає головного підстановки і поле індексується, що є звичайною ситуацією, двигун бази даних може застосувати регулярний вираз до індексу. Так, наприклад, якщо ви пишете

SELECT *
  FROM employees
 WHERE last_name LIKE 'Cav%'

база даних може використовувати індекс на, LAST_NAMEщоб знайти всі рядки, з яких починається прізвище "Cav". З іншого боку, якби у вас було щось подібне

SELECT *
  FROM employees
 WHERE last_name LIKE '%av%'

база даних повинна буде сканувати всю таблицю (або весь індекс) і оцінити вираз по відношенню до повного LAST_NAMEзначення. Очевидно, що це дуже дорого.

Більшість кращих реляційних баз даних мають можливість здійснювати повнотекстовий пошук більш ефективним способом, будуючи різні види індексів та текстових каталогів, але в них не використовується ключове слово LIKE. Наприклад, ось приємна стаття, в якій обговорюється повнотекстовий пошук у PostgreSQL .


4
Oracle може використовувати індекс навіть із провідним відсотком. Якщо дані, що шукаються, являють собою невелику підмножину рядків, то підказка може змусити його використовувати індекс і зробити виконання швидшим. Див laurentschneider.com/wordpress/2009/07 / ... .
Лей Ріффер

1
"сканувати всю таблицю ... Очевидно, що це дуже дорого" - це, скоріше, залежить від таблиці;) ps Чи погоджуєтесь ви LAST_NAMEбути кандидатом (перший стовпець) кластерного індексу? pps, наскільки ця відповідь передбачає, що система бази даних базується на суміжній пам’яті на диску та індексах B-tree?
одного дня, коли

26

На додаток до того, що написав Джастін Кейв, оскільки після PostgreSQL 9.1 ви можете прискорити будь-який пошук за допомогою LIKE( ~~) або ILIKE( ~~*) і основних збігів регулярних виразів також ( ~). Використовуйте класи операторів, надані модулем pg_trgm з індексом GIN або GiST, для прискорення LIKEвиразів, які не ліворуковані . Щоб встановити розширення, запустіть один раз у базі даних:

CREATE EXTENSION pg_trgm;

Створіть індекс форми

CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);

Або:

CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);

Створення та підтримка індексу GIN або GiST несе в собі витрати, але якщо ваша таблиця не надто написана, це чудова функція для вас.

Депес написав чудову статтю у своєму блозі про нову функцію.

GIN або GiST?

Ці два цитати з посібника повинні дати певні вказівки

Вибір між індексацією GiST та GIN залежить від відносних характеристик продуктивності GiST та GIN, які обговорюються в інших місцях. Як правило, індекс GIN швидше шукати, ніж індекс GiST, але повільніше будувати або оновлювати; тому GIN краще підходить для статичних даних, а GiST - для часто оновлюваних даних.

Але для "найближчого сусіда" тип запитів із використанням оператора дистанції <->:

Це може бути досить ефективно реалізовано індексами GiST, але не індексами GIN.


3
Читаючи це, я задумався, чи використовувати GIN чи GiST. Згідно з тим, що я читав, індекси GIN дорожче підтримувати, але швидше шукати, тоді як індекс GiST дешевше підтримувати, але повільніше шукати. Це означає, що індекси GIN, як правило, слід використовувати на відносно статичних даних, тоді як індекси GiST є кращими для більш сильно мутуючих таблиць.
Colin 't Hart

1
@ Colin'tHart: Це взагалі так, але з цього правила є винятки. Розглянемо додаток вище.
Erwin Brandstetter

5

Якщо говорити про MySQL, то позиція символу підключення (%) має значення. Якщо перша частина тексту вказана як where first_name like 'Sta%', то двигун БД буде шукати лише менший підмножина слів, що дивляться на S, потім переходять до St, а потім Sta і т. Д. Якщо ви робите щось на кшталт where first_name like '%stan%', то і ціле сканування стовпець буде потрібно. Ви також можете переглянути повнотекстові покажчики, що також здійснює пошук на природній мові. Ознайомтеся з документами MySQL тут.


1
Чому б почати пошук "S%", коли підрядка визначена на 3 символи (тобто ми знаємо, що рядок не є "Sr%")? Або ви припускали, що у БД є дерево префіксів за атрибутами та надається приклад переходу цього дерева?
Нік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.