SQL Server'da CONTAINS ve LIKE


210

Aşağıdaki sorgulardan hangisi daha hızlıdır (LIKE vs CONTAINS)?

SELECT * FROM table WHERE Column LIKE '%test%';

veya

SELECT * FROM table WHERE Contains(Column, "test");

12
Cevabı kabul et, olur mu?
AgentFire

7
Yıllardır açık değildi adamım.
Chris

Yanıtlar:


174

İkincisi (sizin anlamına gelir CONTAINSve aslında geçerli bir sorguya koymak) daha hızlı olmalıdır, çünkü bazı dizin türleri (bu durumda tam metin dizini) kullanabilir. Tabii ki, sorgunun bu formun yalnızca kullanılabilir eğer sütun tam metin dizini içindedir. Değilse, sadece ilk form kullanılabilir.

LIKE kullanan ilk sorgu, bir joker karakterle başladığı için bir dizin kullanamaz, bu nedenle her zaman tam tablo taraması gerektirir.


CONTAINSSorgu olmalıdır:

SELECT * FROM table WHERE CONTAINS(Column, 'test');

@edze - demek istediğim, zaten bağlı olduğum sayfanın ilk sözü CONTAINSmi? Ne olmuş yani? Sorunun orijinal şekli, Column CONTAIN("%test%",Column)>0geçerli olmayan yere yakındı. Hala tam olarak doğru değil.
Damien_The_Unbeliever

Bu, SharePoint'te bir sorguyu sıralamamıza yardımcı oldu. Başka bir Harika Cevap rozetiniz olsun.
ouflak

14

SQL Server 2012 örneğinde her iki sorguyu da çalıştırdıktan sonra, ilk sorgunun benim durumumda en hızlı olduğunu onaylayabilirim.

LIKEAnahtar kelimeyle yapılan sorgu, kümelenmiş bir dizin taraması gösterdi.

CONTAINSAyrıca tam metin maç için ek operatörleri ile bir kümelenmiş dizin tarama vardı ve bir birleştirme katılmak.

Plan


8
Kümelenmiş dizin yaprak sayfaları vardır tablo. Bir LIKElider joker ile sorgu verimli indeks bölümünü kullanmak mümkün olmayacaktır. Sadece her şeyi taraması gerekecek. Şüphesiz, tam CI taramasının tam metin dizinini kullanan bir sorgudan daha iyi performans gösterdiği bazı durumlar olabilir (belki de satırların çok yüksek bir oranı eşleşiyorsa), bu, genel olarak onaylayabileceğiniz bazı genel kural değildir " ".
Martin Smith

200.000'den fazla kayıt getiren gerçek bir yürütme planına bakıyorum. Her iki sorguyu da toplu olarak koyarsanız, her ikisi de kümelenmiş dizini tarar, ancak buna ek olarak "CONTAINS" sorgusunun FULL TEXT MATCH ve MERGE JOIN ek maliyeti vardır.
MI C

Bir birleştirme birleştirmeyi seçerse, SQL Server satırların% x'inden fazlasını tahmin eder. (Burada X = devrilme noktası ). Bu durumda, her ikisinin de eşit olarak eşleşebileceğini hayal edebilirim. Uygulama planında gösterilen maliyetler sadece tahminidir (fiili planda bile). FT planında ilave yürütme planı operatörleri varken, bazı faydaları vardır. Birleştirme birleşimi, FT sonuçlarının bitmesi durumunda taramanın bitiminden önce durabilir ve ayrıca değerini değerlendirmek zorunda değildir LIKE.
Martin Smith

1
Sql 2012 yürütme planı kontrol etmek için benzer bir sorgu çalıştırdım ve bana bir dizin arama verdi. Belki buradaki örnekte tablo neredeyse boştu. Bazı durumlarda sql, daha hızlı olduğu için indeksi kullanmak yerine çok küçük bir tabloda bir dizin taraması kullanır.
Juan

8

Sorgunuzda bir tire ("-") bulunduğundan bunun CONTAINSdaha uzun sürdüğünü ve kullanıldığını düşünüyorum .Mergeadventure-works.com

Tire bir mola kelimedir böylece CONTAINSiçin tam metin dizini aradı adventureve onu aramış daha works.comve sonuçları birleşti.


8

Ayrıca şunu değiştirmeyi deneyin:

    SELECT * FROM table WHERE Contains(Column, "test") > 0;

Buna:

    SELECT * FROM table WHERE Contains(Column, '"*test*"') > 0;

Birincisi " bu bir testtir " ve " bir test senaryosu plan " gibi değerlere sahip kayıtları bulur .

İkincisi ayrıca " bunu test ediyorum " ve " bu en iyisi " gibi değerleri olan kayıtları bulur .


4
Yıldız işaretini arama teriminden önce ve sonra koymak işe yarıyor mu? Dokümantasyonunu okurken, CONTAINSsadece 'test *' gibi önek terimlerini kullanıyor, ' test' gibi sonek terimlerini değil, '* test ' gibi tam alt dize aramasını değil . Yine de denemedim.
mat forsythe

5
CONTAINS ( docs.microsoft.com/en-us/sql/t-sql/queries/… ) belgelerini okuduysanız , yalnızca önek aranması desteklenir. Ben deneysel olarak bu defalarca denedim ve içerir "Bu en büyük" (SQL Sever içinde) içerir (sütun, '" test "')
cl0rkster
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.