2011-12-02 11 views
6

Trên một số truy vấn SQL, tôi cần kiểm tra xem một trường có bắt đầu bằng một ký tự hay không. Có một số cách để làm điều đó, cái nào tốt hơn trong hiệu suất/tiêu chuẩn?Trên SQL Server (2008), nếu tôi muốn lọc một trường chuỗi bắt đầu bằng thứ gì đó, cách tốt nhất là gì?

Tôi thường sử dụng

tb.field LIKE 'C%' 

nhưng tôi cũng có thể sử dụng

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

Tôi biết rõ những ứng dụng của từng trường hợp, nhưng không phải về hiệu suất.

+0

Tôi không biết chắc chắn, nhưng tôi tưởng tượng ví dụ đầu tiên, bởi vì trong lần thứ hai bạn đang làm một trim và sau đó đi qua tất cả các kết quả một lần nữa để tìm 'C' –

+5

Tốt câu hỏi, nhưng cách tốt nhất để tìm ra điều này là xem các kế hoạch thực hiện thực tế của họ và xem chúng khác nhau ở đâu. –

Trả lời

5

Tôi muốn sử dụng số đầu tiên LIKE C%, nó sẽ sử dụng chỉ mục trên trường nếu có thay vì phải quét toàn bộ bảng.

Nếu bạn thực sự cần bao gồm khoảng trắng LTRIM cắt tỉa trong truy vấn, bạn có thể tạo cột được tính liên tục với giá trị LEFT(LTRIM(tb.Field), 1) và đặt chỉ mục trên đó.

4

LIKE 'C%' sẽ hoạt động tốt hơn LEFT(LTRIM()).

Vị từ LIKE vẫn có thể sử dụng chỉ mục hỗ trợ để lấy dữ liệu bạn đang tìm kiếm. Tôi

Tuy nhiên, khi SQL Server gặp LEFT(LTRIM(tb.Field), 1) = 'C', cơ sở dữ liệu không thể xác định ý của bạn. Để thực hiện một trận đấu, SQL Server phải quét mọi hàng, LTRIM dữ liệu và sau đó kiểm tra ký tự đầu tiên. Kết quả cuối cùng, rất có thể là quét toàn bộ bảng.

0

Truy vấn đầu tiên chỉ là một chút so với truy vấn khác. Tôi đã đo nó với kịch bản đo tốc độ truy vấn của tôi. Hãy thử nó cho mình:

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