2011-12-02 16 views
6

W przypadku kilku zapytań SQL muszę sprawdzić, czy pole zaczyna się od znaku. Istnieje kilka sposobów, aby to zrobić, który z nich jest lepszy pod względem wydajności/standardu?Na serwerze SQL (2008), jeśli chcę filtrować pole łańcucha, które zaczyna się od czegoś, jaki jest najlepszy sposób?

Zwykle używam

tb.field LIKE 'C%' 

ale mogę też użyć

LEFT(LTRIM(tb.Field),1) = 'C' 

Znam dobrze zastosowań każdego przypadku, ale nie pod względem wydajności.

+0

Nie wiem na pewno, ale wyobrażam sobie, pierwszy przykład, ponieważ w drugim robisz wykończenia a następnie przechodząc nad wszystkimi wynikami ponownie znaleźć „C” –

+5

Dobry pytanie, ale najlepszym sposobem, aby to odkryć, jest obejrzenie ich rzeczywistych planów wykonania i sprawdzenie, gdzie są one różne. –

Odpowiedz

5

Poszedłbym z pierwszym LIKE C%, użyje indeksu na polu, jeśli jest taki, zamiast konieczności pełnego skanowania tabeli.

Jeśli naprawdę potrzebujesz uwzględnić przycinanie w białej spacji, możesz utworzyć kolumnę z utrwaloną wartością o wartości LEFT(LTRIM(tb.Field), 1) i umieścić na niej indeks.

4

LIKE 'C%' będzie działać lepiej niż LEFT(LTRIM()).

Predykat LIKE może nadal korzystać z indeksu pomocniczego, aby uzyskać dane, których szukasz. I

Jednak, gdy SQL Server napotka LEFT(LTRIM(tb.Field), 1) = 'C', baza danych nie może określić, co masz na myśli. Aby wykonać dopasowanie, SQL Server musi przeskanować każdy wiersz, LTRIM danych, a następnie zbadać pierwszy znak. Końcowym rezultatem jest najprawdopodobniej pełne skanowanie tabeli.

0

Pierwsze zapytanie jest tylko trochę inne. Zmierzyłem to za pomocą mojego skryptu pomiaru prędkości zapytania. Spróbuj to sam:

DECLARE @Measurements TABLE(
    MeasuredTime INT NOT NULL 
) 

DECLARE @ExecutionTime INT 
DECLARE @TimesMeasured INT 
SET @TimesMeasured = 0 


WHILE @TimesMeasured < 1000 
BEGIN 
    DECLARE @StartTime DATETIME 

    SET @StartTime = GETDATE() 

    -- your select .. or what every query 

    INSERT INTO @Measurements 
    SELECT DATEDIFF(millisecond, @StartTime, getdate()) 

    SET @TimesMeasured = @TimesMeasured + 1 
END 

SELECT @AvgTime = AVG(MeasuredTime) FROM @Measurements