THÍCH được thực hiện như thế nào?


22

Bất cứ ai cũng có thể giải thích cách toán tử THÍCH được triển khai trong các hệ thống cơ sở dữ liệu hiện tại (ví dụ: MySQL hoặc Postgres)? hoặc chỉ cho tôi một số tài liệu tham khảo giải thích nó?

Cách tiếp cận ngây thơ sẽ là kiểm tra từng bản ghi, thực hiện một biểu thức chính quy hoặc một phần chuỗi khớp trên lĩnh vực quan tâm, nhưng tôi có cảm giác (hy vọng) rằng các hệ thống này làm điều gì đó thông minh hơn.

Câu trả lời:


19

Không, đó là những gì họ đang làm. Bây giờ, nếu không có ký tự đại diện hàng đầu và trường được lập chỉ mục, đó là tình huống thông thường, công cụ cơ sở dữ liệu có thể áp dụng biểu thức chính quy cho chỉ mục. Vì vậy, ví dụ, nếu bạn viết

SELECT *
  FROM employees
 WHERE last_name LIKE 'Cav%'

cơ sở dữ liệu có thể sử dụng chỉ mục trên LAST_NAMEđể tìm tất cả các hàng nơi tên cuối cùng bắt đầu 'Cav'. Mặt khác, nếu bạn có một cái gì đó như

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

cơ sở dữ liệu sẽ phải quét toàn bộ bảng (hoặc toàn bộ chỉ mục) và đánh giá biểu thức dựa trên LAST_NAMEgiá trị đầy đủ . Rõ ràng, điều đó rất tốn kém.

Hầu hết các cơ sở dữ liệu quan hệ tốt hơn đều có phương tiện để thực hiện tìm kiếm toàn văn một cách hiệu quả hơn bằng cách xây dựng các loại chỉ mục và danh mục văn bản khác nhau nhưng chúng không sử dụng từ khóa THÍCH. Ví dụ, đây là một bài viết hay thảo luận về tìm kiếm toàn văn bản trong PostgreSQL .


4
Oracle có thể sử dụng một chỉ mục ngay cả với tỷ lệ phần trăm hàng đầu. Nếu dữ liệu đang được tìm kiếm đại diện cho một tập hợp con nhỏ của các hàng thì gợi ý có thể buộc nó sử dụng một chỉ mục và thực hiện nhanh hơn. Xem laurentschneider.com/wordpress/2009/07/ .
Leigh Riffel

1
"quét toàn bộ bảng ... Rõ ràng, điều đó rất tốn kém" - điều đó phụ thuộc vào bảng;) ps bạn có đồng ý LAST_NAMElàm ứng cử viên cho (cột đầu tiên trong) chỉ mục được nhóm không? pps đến mức nào thì câu trả lời này giả định hệ thống cơ sở dữ liệu dựa trên lưu trữ liền kề trên các chỉ mục của đĩa và cây B?
ngày

26

Ngoài những gì Justin Cave đã viết, kể từ PostgreQuery 9.1, bạn có thể tăng tốc bất kỳ tìm kiếm nào với LIKE( ~~) hoặc ILIKE( ~~*) và các biểu thức chính quy cơ bản khớp ( ~). Sử dụng các lớp toán tử được cung cấp bởi mô-đun pg_trgm với chỉ số GIN hoặc GiST để tăng tốc các LIKEbiểu thức không được neo trái. Để cài đặt tiện ích mở rộng, hãy chạy một lần cho mỗi cơ sở dữ liệu:

CREATE EXTENSION pg_trgm;

Tạo một chỉ mục của biểu mẫu

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

Hoặc là:

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

Tạo và duy trì chỉ số GIN hoặc GiST mang lại chi phí, nhưng nếu bảng của bạn không được viết nhiều, đây là một tính năng tuyệt vời cho bạn.

Depesz đã viết một bài báo xuất sắc trong blog của mình về tính năng mới.

GIN hay GiST?

Hai trích dẫn từ hướng dẫn sẽ cung cấp một số hướng dẫn

Sự lựa chọn giữa lập chỉ mục GiST và GIN phụ thuộc vào đặc tính hiệu suất tương đối của GiST và GIN, được thảo luận ở nơi khác. Theo nguyên tắc thông thường, chỉ mục GIN tìm kiếm nhanh hơn chỉ số GiST, nhưng chậm hơn để xây dựng hoặc cập nhật; vì vậy GIN phù hợp hơn với dữ liệu tĩnh và GiST cho dữ liệu thường được cập nhật.

Nhưng đối với loại truy vấn "hàng xóm gần nhất" với toán tử khoảng cách <->:

Điều này có thể được thực hiện khá hiệu quả bởi các chỉ mục GiST, nhưng không phải bởi các chỉ mục GIN.


3
Đọc đến đây tôi băn khoăn không biết nên sử dụng GIN hay GiST. Theo những gì tôi đọc được, các chỉ mục GIN đắt hơn để duy trì nhưng tìm kiếm nhanh hơn, trong khi chỉ số GiST rẻ hơn để duy trì nhưng tìm kiếm chậm hơn. Điều này có nghĩa là các chỉ mục GIN thường được sử dụng trên dữ liệu tương đối tĩnh trong khi các chỉ mục GiST được ưu tiên trên các bảng đột biến nặng hơn.
Colin 't Hart

1
@ Colin'tHart: Điều đó thường đúng, nhưng có những ngoại lệ cho quy tắc. Hãy xem xét phần phụ lục ở trên.
Erwin Brandstetter

5

Nói về MySQL, vị trí của ký tự đại diện (%) tạo nên sự khác biệt. Nếu phần đầu tiên của văn bản được chỉ định như thế where first_name like 'Sta%', thì công cụ DB sẽ chỉ tìm kiếm một tập hợp nhỏ hơn các từ đang nhìn chằm chằm vào S, sau đó chuyển đến St, và sau đó là Sta, v.v. Nếu bạn làm một cái gì đó như where first_name like '%stan%', sau đó và quét toàn bộ cột sẽ được yêu cầu. Bạn cũng có thể xem xét các chỉ mục toàn văn cũng tìm kiếm ngôn ngữ tự nhiên. Kiểm tra các tài liệu MySQL ở đây.


1
Tại sao nó bắt đầu tìm kiếm "S%" khi chuỗi con được xác định thành 3 ký tự (nghĩa là chúng ta biết chuỗi không phải là "Sr%")? Hay bạn đã giả sử DB có cây tiền tố trên các thuộc tính và cung cấp một ví dụ về việc vượt qua cây này?
Nick
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.