Yanıtlar:
Genel olarak, "kesinlik" ve "geri çağırma" arasında bir denge vardır. Yüksek hassasiyet, daha az alakasız sonucun sunulduğu (yanlış pozitiflerin olmadığı) anlamına gelirken, yüksek hatırlama, daha az alakalı sonucun eksik olduğu (yanlış negatiflerin olmadığı) anlamına gelir. LIKE operatörünü kullanmak, geri çağırmadan ödün vermeden size% 100 hassasiyet sağlar. Tam metin arama özelliği, daha iyi hatırlama için hassasiyeti azaltmanız için size büyük esneklik sağlar.
Çoğu tam metin arama uygulaması "ters çevrilmiş dizin" kullanır. Bu, anahtarların ayrı terimler olduğu ve ilişkili değerlerin, terimi içeren kayıt kümeleri olduğu bir dizindir. Tam metin araması, bu kayıt setlerinin kesişimini, birleşimini vb. Hesaplamak için optimize edilmiştir ve genellikle belirli bir kaydın arama anahtar kelimeleriyle ne kadar güçlü eşleştiğini ölçmek için bir sıralama algoritması sağlar.
SQL LIKE operatörü son derece verimsiz olabilir. Dizine eklenmemiş bir sütuna uygularsanız, eşleşmeleri bulmak için tam bir tarama kullanılır (dizine eklenmemiş bir alandaki herhangi bir sorgu gibi). Sütun dizine alınmışsa, eşleme dizin anahtarlarına karşı gerçekleştirilebilir, ancak çoğu dizin aramasından çok daha az verimlilikle. En kötü durumda, LIKE kalıbı, her dizin anahtarının incelenmesini gerektiren önde gelen joker karakterlere sahip olacaktır. Bunun aksine, birçok bilgi erişim sistemi, seçilen alanlardaki sonek ağaçlarını önceden derleyerek önde gelen joker karakterleri destekleyebilir.
Tam metin aramaya özgü diğer özellikler şunlardır:
FTS, birçok kayıtta hızlı arama yapmak için bir metin alanındaki tek tek kelimelerin indekslenmesini içerir. LIKE'ı kullanmak, yine de alan içinde bir dizi araması (doğrusal veya benzeri) yapmanızı gerektirir.
MySQL, etkinleştirilmiş tam metin arama sütununun sözcüklerinden bir dizin oluşturur ve bu dizinde arama yapar. MySQL, arama sorgusuyla eşleşen satırları belirlemek için gelişmiş bir algoritma kullanır.
Ayrıca, bu SO cevabından :
Tam metin aramanın birkaç avantajı vardır.
indeksleme:
Gibi bir şey:
WHERE Foo LIKE '%Bar';
Bir dizinden yararlanılamaz. Her satıra bakmalı ve eşleşip eşleşmediğini görmelidir. Ancak tam metin dizini olabilir. Aslında, tam metin dizinler, eşleşen kelimelerin sırası, bu kelimelerin birbirine ne kadar yakın olduğu vb. Açısından çok daha fazla esneklik sağlayabilir.
Stemming:
Tam metin araması, kelimelerin köküne neden olabilir. Koşuyu ararsanız, "koştu" veya "koşuyor" için sonuçları alabilirsiniz. Çoğu tam metin motorunun çeşitli dillerde kök sözlükleri vardır.
Ağırlıklı Sonuçlar:
Bir tam metin dizini birden çok sütunu kapsayabilir. Örneğin, "şeftali turtası" için arama yapabilirsiniz ve dizin bir başlık, anahtar kelimeler ve bir gövde içerebilir. Başlıkla eşleşen sonuçlar, daha alakalı olarak daha yüksek ağırlıklı olabilir ve en üstte gösterilecek şekilde sıralanabilir.
Dezavantajları:
Tam metin dizini, potansiyel olarak çok büyük olabilir, standart bir B-TREE dizininden birçok kez daha büyük olabilir. Bu nedenle, veritabanı örnekleri sunan birçok barındırılan sağlayıcı bu özelliği devre dışı bırakır veya en azından bunun için ekstra ücret alır. Örneğin, son kontrol ettiğimde, Windows Azure tam metin sorgularını desteklemiyordu.
Tam metin dizinleri de daha yavaş güncellenebilir. Veriler çok değişirse, standart dizinlere kıyasla bazı gecikmeli güncelleme dizinleri olabilir.
Like yalnızca joker karakterler kullanır ve o kadar da güçlü değildir.
Tam metin, And, Or, Not, hatta benzer sesli sonuçlar (SOUNDEX) ve daha pek çok öğe dahil olmak üzere çok daha karmaşık aramalara izin verir.
Nelerin mevcut olduğunu daha iyi anlamak için SQL CONTAINS () FREETEXT () ve ilgili Tam Metin arama öğelerine bakmaya başlayacaktım.
Gerçek fark, tarama metodolojileridir. Tam metin araması için, sözcükler (terimler) karma anahtarlar olarak kullanılır - her biri anahtarların (terimlerin) içinde göründüğü bir dizi belgeyle ilişkilendirilir. Bunun gibi:
Document sets = {d1, d2, d3, d4, ... dn}
Term sets = {t1, t2, t3, .. tn}
Şimdi dönem-belge matrisi (hangi terim hangi belgenin üyesi) şu şekilde temsil edilebilir:
t1 -> {d1, d5, d9,.. dn}
t2 -> {d11, d50, d2,.. dn}
t3 -> {d23, d67, d34,.. dn}
:
tn -> {d90, d87, d57,.. dn}
"Bana t1 kelimesini / terimini içeren tüm belgeleri getir" sorusu geldiğinde istek geldiğinde - belge kümesi {d1, d5, d9,.. dn
} döndürülür.
Belgeleri depolamak için normalleştirilmiş bir tablo şemasını kırabilirsiniz - MySQL tablosundaki her satır "belge" olarak kabul edilir ve bir TEXT sütunu bir paragraf içerebilir vb. Tersine çevrilmiş dizin, hash anahtarları ve satır kimlikleri olarak terimleri içerecektir. belge kimlikleri olarak.
Bu SQL sorgusunun az veya çok O (1) performansına sahip olacağını unutmayın. Sorgu şunlardan bağımsız olacaktır
Örneğin bu SQL, verilen XYZ kelimesiyle eşleşen tüm satırları çıkarmak için çalıştırılabilir:
SELECT *
FROM my_table
WHERE MATCH (my_text_column) against ('XYZ' IN boolean mode) ;
Uyarı: Bu sorguya ORDER BY eklerseniz, çalışma zamanlarınız, biri eşleşen satırların / belgelerin sayısı olan birkaç parametreye göre değişecektir. Bu yüzden sakının.
Ancak LIKE'ın bundan hiçbir şeyi yok. Cümle / dizeyi doğrusal olarak taramaya ve eşleşen tüm terimleri bulmaya zorlanır. Joker kart eklemek karışıklığa katkıda bulunur. Tahmin edebileceğiniz gibi küçük uzunluktaki dizeler için harika çalışıyor, ancak daha uzun cümleler için sefil bir şekilde başarısız olacak. Ve bir paragraf veya tam bir metin sayfası varken kesinlikle karşılaştırılamaz.
FTS daha etkilidir, güçlüdür (özellikle Kelime Kırıcılar ve kök ayırma işlevleri için) ... ancak gereksinimlerinizi kontrol edin çünkü bazen DB'ler tüm dilleri desteklemez, örneğin MSSQL Yunanca'yı desteklemez (bu sayfaya bakın http: // msdn. microsoft.com/en-us/library/ms176076(v=sql.110).aspx )