LIKE nasıl uygulanır?


22

LIKE operatörünün mevcut veritabanı sistemlerinde nasıl uygulandığını açıklayabilir (örneğin, MySQL veya Postgres)? ya da beni açıklayan bazı referanslara işaret?

Naif bir yaklaşım, her bir alanı incelemek, ilgilenilen alanda düzenli bir ifade ya da kısmi bir dize eşleştirmesi yapmak olacaktır, ancak bu sistemlerin daha akıllıca bir şey yaptığı hissine sahibim (umudum).

Yanıtlar:


19

Hayır, yaptıkları şey buydu. Şimdi, önde gelen bir joker karakter yoksa ve alan dizine eklenirse, normal durum budur, veritabanı motoru normal ifadeyi dizine uygulayabilir. Mesela eğer yazarsanız

SELECT *
  FROM employees
 WHERE last_name LIKE 'Cav%'

veritabanı LAST_NAMEsoyadı 'Cav' ile başlayan tüm satırları bulmak için dizini kullanabilir . Öte yandan, eğer senin gibi bir şeylerin olsaydı

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

Veritabanının tüm tabloyu (veya tüm dizini) taraması ve ifadeyi tam LAST_NAMEdeğerle karşılaştırması gerekir. Açıkçası, bu çok pahalı.

Daha iyi ilişkisel veritabanlarının çoğunda, farklı türlerde dizinler ve metin katalogları oluşturarak tam metin aramayı daha verimli bir şekilde yapma olanakları vardır, ancak bunlar LIKE anahtar sözcüğünü kullanmaz. Örneğin, PostgreSQL'de tam metin aramayı tartışan güzel bir makale .


4
Oracle, yüzde bile olsa bir endeks kullanabilir. Aranan veriler satırların küçük bir alt kümesini temsil ediyorsa ipucu onu bir dizin kullanmaya ve yürütmeyi daha hızlı hale getirmeye zorlayabilir. Bakınız laurentschneider.com/wordpress/2009/07/… .
Leigh Riffel

1
"tüm tabloyu tara ... Açıkçası, bu çok pahalı" - bu tabloya bağlı olarak;) ps LAST_NAMEkümelenmiş dizine (ilk sütundaki) aday olmayı kabul ediyor musunuz? pps, bu cevabın ne dereceye kadar veri tabanı sisteminin diskte ve B-ağaç indekslerinde bitişik depolamaya dayandığını varsayar?
gün,

26

Justin Cave’in yazdıklarına ek olarak, PostgreSQL 9.1’den bu yana ( ) veya ( ) ile herhangi bir aramayı hızlandırabilir ve normal düzenli ifadenin de ( ) ile eşleşmesini sağlayabilirsiniz . Bağlantılı olmayan ifadeleri hızlandırmak için pg_trgm modülü tarafından sağlanan operatör sınıflarını bir GIN veya GiST endeksi ile kullanın . Uzantıyı yüklemek için veritabanı başına bir kez çalıştırın:LIKE~~ILIKE~~*~LIKE

CREATE EXTENSION pg_trgm;

Formun bir dizinini oluşturun

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

Veya:

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

Bir GIN veya GiST endeksi oluşturmak ve sürdürmek bir maliyet taşır, ancak tablonuz yoğun bir şekilde yazılmış değilse, bu sizin için harika bir özelliktir.

Depesz , blogunda yeni özellik hakkında mükemmel bir makale yazdı .

Cin mi GiST mi?

Kılavuzdan bu iki alıntı bazı rehberlik sağlamalıdır

GiST ve GIN indeksleme arasındaki seçim, başka bir yerde tartışılan GiST ve GIN'in göreceli performans özelliklerine bağlıdır. Genel bir kural olarak, bir GIN endeksi aramak için bir GiST endeksinden daha hızlıdır, ancak oluşturulması ya da güncellenmesi daha yavaştır; Bu nedenle, GIN statik veriler için ve GiST sıklıkla güncellenen veriler için daha uygundur.

Ancak, uzaklık operatörünü kullanan "en yakın komşu" türü için sorgular <->:

Bu, GiST endeksleri tarafından oldukça verimli bir şekilde uygulanabilir, ancak GIN endeksleri tarafından uygulanamaz.


3
Bunu okumak GIN mi yoksa GiST mi kullanılacağını merak ettim. Ne okuduğuma göre, GIN endeksleri bakımı daha pahalı, ancak aramaları daha hızlı, GiST endeksi bakımı daha ucuz, ancak aramaları daha yavaş. Bu, GIN endekslerinin genellikle nispeten statik verilerde kullanılması gerektiği ve GiST endekslerinin daha yoğun mutasyon tablolarında tercih edildiği anlamına gelir.
Colin 't Hart

1
@ Colin'tHart: Bu genel olarak doğrudur, ancak kuralın istisnaları vardır. Yukarıdaki eki düşünün.
Erwin Brandstetter

5

MySQL hakkında konuşmak, joker karakterin (%) konumu bir fark yaratıyor. Metnin ilk bölümü gibi belirtilirse where first_name like 'Sta%', DB motoru yalnızca S ile başlayan, sonra St ve ardından Sta vb. Gibi sözcüklerin daha küçük bir alt kümesini arayacaktır where first_name like '%stan%'. sütun gerekli olacak. Ayrıca doğal dil aramaları yapan tam metin dizinlerini de inceleyebilirsiniz. MySQL dokümanlarına buradan göz atın.


1
Alt dize 3 karakter olarak tanımlandığında neden "S%" aramaya başlasın (örneğin, dizginin "Sr%" olmadığını biliyoruz)? Yoksa DB'nin nitelikler üzerinde bir önek ağacı olduğunu ve bu ağacı geçmenin bir örneğini sağladığını mı düşünüyorsunuz?
Nick,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.