To pytanie omija to, nad czym się zastanawiam, ale odpowiedzi nie dotyczą go dokładnie.
Wydawałoby się, że generalnie „=” jest szybsze niż „like”, gdy używa się symboli wieloznacznych. Wydaje się, że jest to powszechna mądrość. Załóżmy jednak, że mam kolumnę zawierającą ograniczoną liczbę różnych stałych, zakodowanych na stałe identyfikatorów varchar i chcę wybrać wszystkie wiersze pasujące do jednego z nich:
select * from table where value like 'abc%'
i
select * from table where value = 'abcdefghijklmn'
„Like” powinno wymagać tylko przetestowania pierwszych trzech znaków, aby znaleźć dopasowanie, podczas gdy „=” musi porównać cały ciąg. W tym przypadku wydaje mi się, że „lubienie” miałoby przewagę, przy czym wszystkie inne rzeczy byłyby równe.
Jest to ogólne, akademickie pytanie, więc nie powinno mieć znaczenia, która baza danych, ale powstało przy użyciu SQL Server 2005.
źródło
value
jest indeksowany. Jeśli tak,=
jest to proste wyszukiwanie bez konieczności skanowania tabeli i usunie spodnie z każdegoLIKE
stwierdzenia, które do niego rzucisz.LIKE
z symbolem wieloznacznym na końcu jest SARGable i dlatego będzie wykonywać przeszukiwanie zakresu na indeksie, bez widocznego skanowania tabeli. To szukanie zakresu może dość dobrze konkurować z=
instrukcją, aw wielu przypadkach (np. Jeśli wszystkie spełniające wymagania wiersze znajdują się na jednej stronie, warunek nie jest nieprawdopodobny) może mieć dokładnie taką samą wydajność, pociągając za sobą taką samą liczbę odczytów.Odpowiedzi:
Zobacz https://web.archive.org/web/20150209022016/http://myitforum.com/cs2/blogs/jnelson/archive/2007/11/16/108354.aspx
Cytat z tego miejsca:
źródło
To wymierna różnica.
Uruchom następujące:
Create Table #TempTester (id int, col1 varchar(20), value varchar(20)) go INSERT INTO #TempTester (id, col1, value) VALUES (1, 'this is #1', 'abcdefghij') GO INSERT INTO #TempTester (id, col1, value) VALUES (2, 'this is #2', 'foob'), (3, 'this is #3', 'abdefghic'), (4, 'this is #4', 'other'), (5, 'this is #5', 'zyx'), (6, 'this is #6', 'zyx'), (7, 'this is #7', 'zyx'), (8, 'this is #8', 'klm'), (9, 'this is #9', 'klm'), (10, 'this is #10', 'zyx') GO 10000 CREATE CLUSTERED INDEX ixId ON #TempTester(id)CREATE CLUSTERED INDEX ixId ON #TempTester(id) CREATE NONCLUSTERED INDEX ixTesting ON #TempTester(value)
Następnie:
SET SHOWPLAN_XML ON
Następnie:
SELECT * FROM #TempTester WHERE value LIKE 'abc%' SELECT * FROM #TempTester WHERE value = 'abcdefghij'
Wynikowy plan wykonania pokazuje, że koszt pierwszej operacji,
LIKE
porównania, jest około 10 razy droższy niż=
porównanie.Jeśli możesz użyć
=
porównania, zrób to.źródło
19.95
kosztach SQL Server w dodatkowych 19 kluczach wyszukiwania, które nigdy nie pojawiają się w rzeczywistości (nawet w rzeczywistym planie wykonania pokazane koszty są oparte na szacunkowym koszcie poddrzewa)LIKE
, 203 ms dla=
. Spodziewam się, że gdybym przeprowadził więcej testów i wziął dokładne średnie, nie byłoby prawdziwej różnicy między #temp a prawdziwym stołem.Należy również pamiętać, że podczas używania
like
niektóre odmiany sql będą ignorować indeksy, a to zabije wydajność. Jest to szczególnie ważne, jeśli nie używasz wzorca „zaczyna się od”, jak w przykładzie.Naprawdę powinieneś spojrzeć na plan wykonania zapytania i zobaczyć, co robi, zgaduj jak najmniej.
Biorąc to pod uwagę, wzorzec „zaczyna się od” może i jest zoptymalizowany na serwerze sql. To będzie użyć indeksu tabeli. EF 4,0 przełącza się
like
doStartsWith
tego samego powodu.źródło
Jeśli nie
value
jest indeksowany, oba powodują skanowanie tabeli. Różnica wydajności w tym scenariuszu będzie znikoma.Jeśli
value
jest indeksowane, jak Daniel wskazuje w swoim komentarzu,=
spowoduje to przeszukanie indeksu, które jest wydajnością O (log N). LIKE będzie (najprawdopodobniej - w zależności od sposobu selektywnej jest) w wyniku częściowego skanowania indeksu>= 'abc'
i< 'abd'
co będzie wymagało więcej wysiłku niż=
.Zauważ, że mówię tutaj o SQL Server - nie wszystkie DBMS-y będą miłe z LIKE.
źródło
=
przypadek, jak ilike '...%'
przypadek zachowują się tak samo, jeśli sql rozpoznaje wzorzec (i robi), ponieważ w obu przypadkach poddrzewa są wybierane na podstawie relacji porównania.'abd'
.Zadajesz złe pytanie. W bazach danych nie liczy się wydajność operatora, zawsze liczy się SARGability wyrażenia i pokrycie całego zapytania. Wydajność samego operatora jest w dużej mierze nieistotna.
Jak więc zrobić
LIKE
i=
porównać pod względem SARGability?LIKE
, gdy jest używane z wyrażeniem, które nie zaczyna się od stałej (np. gdy jest używaneLIKE '%something'
), jest z definicji inne niż SARGabale. Ale czy to czyni=
lubLIKE 'something%'
SARGable? Nie. Podobnie jak w przypadku każdego pytania o wydajność SQL, odpowiedź nie leży w zapytaniu o tekst, ale o wdrożonym schemacie. Te wyrażenia mogą być SARGable, jeśli istnieje indeks, który je spełnia.Tak więc, prawdę mówiąc, istnieją niewielkie różnice między
=
iLIKE
. Ale pytanie, czy jeden operator lub inny operator jest „szybszy” w SQL, jest jak pytanie „Co jedzie szybciej, czerwony samochód czy niebieski samochód?”. Powinieneś przestać zadawać pytania o rozmiar silnika i masę pojazdu, a nie o kolor ... Aby podejść do pytań o optymalizację tabel relacyjnych, miejscem do spojrzenia jest twoje indeksy i twoje wyrażenia w klauzuli WHERE (i innych klauzulach, ale zwykle zaczyna się od GDZIE).źródło
Osobisty przykład z użyciem mysql 5.5: miałem sprzężenie wewnętrzne między 2 tabelami, jednym z 3 milionów wierszy i jednym z 10 000 wierszy.
W przypadku użycia polubienia w indeksie jak poniżej (bez symboli wieloznacznych) zajęło to około 30 sekund:
używając „wyjaśnienia” otrzymuję:
W przypadku użycia znaku „=” w tym samym zapytaniu zajęło to około 0,1 sekundy:
Używając opcji „wyjaśnij”, otrzymuję:
Jak widać,
like
całkowicie anulowano przeszukiwanie indeksu, więc zapytanie zajęło 300 razy więcej czasu.źródło
Może szukasz informacji o wyszukiwaniu pełnotekstowym .
źródło
Po pierwsze,
nie zawsze są równi
select 'Hello' from dual where 'Hello ' like 'Hello'; select 'Hello' from dual where 'Hello ' = 'Hello';
kiedy sprawy nie zawsze są równe, mówienie o ich wynikach nie jest tak istotne.
Jeśli pracujesz na łańcuchach i tylko zmiennych typu char, możesz mówić o wydajności. Ale nie używaj like i "=" jako ogólnie wymiennych.
Jak można zobaczyć w wielu postach (powyższe i inne pytania), w przypadkach, gdy są one równe, działanie podobnego jest wolniejsze ze względu na dopasowanie wzorców (sortowanie)
źródło
'Hello '
jestVARCHAR
(domyślnie), masz rację, ale jeśli to jestCHAR
, nie masz. Rzuć to na aCHAR(7)
i oba zwracają prawdę. Poza tym, co do cholery robisz, skoro nieTRIM
robisz swoich varcharów? (uwaga: tak jest przynajmniej wSQL Server 2008r2
)