LIKE vs CONTAIN di SQL Server


210

Yang mana dari pertanyaan berikut yang lebih cepat (LIKE vs CONTAIN)?

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

atau

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

12
Terima jawaban, bukan?
AgentFire

7
Dia sudah bertahun-tahun tidak hidup.
Chris

Jawaban:


174

Yang kedua (dengan asumsi Anda berarti CONTAINS, dan benar-benar memasukkannya ke dalam kueri yang valid) harus lebih cepat, karena dapat menggunakan beberapa bentuk indeks (dalam hal ini, indeks teks lengkap). Tentu saja, bentuk kueri ini hanya tersedia jika kolom dalam indeks teks lengkap. Jika tidak, maka hanya formulir pertama yang tersedia.

Kueri pertama, menggunakan LIKE, tidak akan dapat menggunakan indeks, karena dimulai dengan wildcard, jadi akan selalu memerlukan pemindaian tabel penuh.


The CONTAINSpermintaan harus:

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

@edze - maksud Anda, halaman yang sama yang sudah ditautkan untuk menjadi penyebutan pertama saya CONTAINS? Apa itu? Bentuk asli dari pertanyaan tersebut Column CONTAIN("%test%",Column)>0adalah mana yang hampir tidak valid. Itu masih belum sepenuhnya benar.
Damien_The_Unbeliever

Ini membantu kami memilah kueri di SharePoint. Punya lagi lencana Jawaban Luar Biasa.
ouflak

14

Setelah menjalankan kedua kueri pada contoh SQL Server 2012, saya dapat mengonfirmasi permintaan pertama tercepat dalam kasus saya.

Kueri dengan LIKEkata kunci menunjukkan pemindaian indeks berkerumun.

The CONTAINSjuga memiliki indeks scan berkerumun dengan operator tambahan untuk pertandingan teks lengkap dan gabungan bergabung.

Rencana


8
Halaman daun indeks berkerumun adalah tabel. Sebuah LIKEquery dengan wildcard terkemuka tidak akan dapat menggunakan bagian indeks efisien. Ini perlu memindai semuanya. Meskipun tidak diragukan lagi mungkin ada beberapa keadaan di mana pemindaian CI lengkap berkinerja lebih baik daripada permintaan menggunakan indeks teks lengkap (mungkin jika proporsi baris yang sangat tinggi cocok misalnya), ini sebagian besar akan menjadi pengecualian, bukan aturan umum yang Anda "bisa konfirmasi ".
Martin Smith

Yah saya sedang melihat rencana pelaksanaan yang sebenarnya mengambil lebih dari 200.000 catatan. Menempatkan kedua kueri dalam satu batch, keduanya memindai indeks berkerumun, tetapi di samping itu kueri "MENGANDUNG" memang memiliki biaya tambahan FULL TEXT MATCH dan MERGE JOIN.
MI C

Jika memilih gabungan bergabung maka SQL Server memperkirakan lebih dari x% dari baris akan berakhir sesuai dengan predikat. (Di mana X = titik kritis ). Kalau begitu aku bayangkan keduanya bisa sama rata. Biaya yang ditunjukkan dalam rencana eksekusi hanyalah perkiraan (bahkan dalam rencana sebenarnya). Sementara ada operator rencana eksekusi tambahan dalam rencana FT itu memang memiliki beberapa manfaat. Gabungan gabungan dapat berhenti sebelum akhir pemindaian ketika kehabisan hasil FT dan juga tidak harus mengevaluasi LIKE.
Martin Smith

1
Saya telah menjalankan permintaan serupa untuk memeriksa rencana pelaksanaan di sql 2012 dan itu memberi saya Indeks Mencari. Mungkin dalam contoh di sini meja hampir kosong. Dalam beberapa kasus sql menggunakan pemindaian indeks dalam tabel yang sangat kecil sebagai gantinya untuk menggunakan indeks karena lebih cepat.
Juan

8

Saya pikir itu CONTAINSmembutuhkan waktu lebih lama dan digunakan Mergekarena Anda memiliki tanda hubung ("-") dalam permintaan Andaadventure-works.com .

Tanda hubung adalah kata istirahat sehingga CONTAINSpencarian indeks teks lengkap untuk adventuredan daripada mencari works.comdan menggabungkan hasilnya.


8

Coba juga ubah dari ini:

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

Untuk ini:

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

Yang pertama akan menemukan catatan dengan nilai-nilai seperti " ini adalah tes " dan " kasus uji adalah rencananya ".

Yang terakhir juga akan menemukan catatan dengan nilai-nilai seperti " saya menguji ini " dan " ini adalah yang terbesar ".


4
Apakah menempatkan tanda bintang sebelum dan sesudah istilah pencarian berfungsi? Dalam membaca dokumentasi untuk CONTAINS, itu hanya menyebutkan menggunakan istilah awalan seperti 'test *', bukan akhiran istilah seperti ' test' dan bukan pencarian substring penuh seperti '* test '. Saya belum mencobanya.
matt forsythe

5
Jika Anda membaca dokumentasi untuk CONTAINS ( docs.microsoft.com/en-us/sql/t-sql/queries/… ), hanya mencari awalan yang didukung. Saya telah mencoba ini beberapa kali secara eksperimental dan tidak mungkin untuk menemukan "ini adalah yang terbesar" (dalam SQL Sever) dengan Berisi (Kolom, '" tes "')
cl0rkster
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.