2016-02-02 15 views
7

Tôi đang sử dụng .NET framework 4.5.1 LINQ to SQL.Truy vấn đơn chậm hơn 3 truy vấn

Tôi có lớp sản phẩm này sử dụng mã đầu tiên:

public class Part 
{ 
    public int PartID { get; set; } 

    [Required(ErrorMessage = "xxx")]   
    public string Title { get; set; } 

    [MaxLength(50)] 
    [Index(IsClustered = false, IsUnique = false,Order =1)] 
    public string Part_Number { get; set; } 

    [MaxLength(50)] 
    [Index(IsClustered = false, IsUnique = false, Order = 2)] 
    public string Manufacturer_Number { get; set; } 
} 

tôi có khoảng 2500000 của những đối tượng trong cơ sở dữ liệu.

tiếp cận đầu tiên

var query = db.Parts.Where(s => s.Manufacturer_Number == sstring).ToList();     
query.AddRange(db.Parts.Where(s => s.Part_Number == sstring).ToList()); 
query.AddRange(db.Parts.Where(s => s.Title == sstring).ToList()); 

cách tiếp cận thứ hai

var query = db.Parts.Where(s => s.Manufacturer_Number == sstring 
|| s.Part_Number == sstring || s.Title == sstring).ToList(); 

Phương pháp đầu tiên là nhanh hơn so với phương pháp thứ hai 100 lần. Bất cứ ai có thể giải thích điều này?

+8

Bạn nên xem SQL được proqused bởi LINQ của bạn và sau đó kiểm tra kế hoạch thực hiện trong ManagmentStudio của bạn. Có thể là bạn có chỉ mục trên mỗi trường và các truy vấn đơn giản có thể sử dụng chúng nhưng không phải là chỉ mục cuối cùng của bạn. –

+1

Tôi hy vọng anh ta có chỉ mục nếu bạn có 2,5 triệu bản ghi trong một bảng ... –

+0

Chính xác bạn muốn đạt được điều gì ..? –

Trả lời

1

Đầu tiên không có chỉ mục về tiêu đề, tôi thấy khó tin rằng bạn đang nhận được hành vi mà bạn khiếu nại.

Đặt thống kê ở mức tối thiểu và thêm kết quả vào câu hỏi này.

Nhưng điều đó nói rằng, cách tiếp cận đầu tiên thực sự là ba chuyến đi tới cơ sở dữ liệu, nhưng sẽ tận dụng chỉ mục được tạo ra.

Cách tiếp cận thứ hai là một chuyến đi duy nhất tới cơ sở dữ liệu nhưng chắc chắn sẽ dẫn đến quét toàn bộ bảng, với 2.500.000 hàng có thể mất một lượng thời gian không nhỏ.

+1

Nếu tất cả các trường được lập chỉ mục, điều này sẽ không dẫn đến việc quét bảng. Các trường hợp duy nhất tôi có thể nghĩ về nơi có * có thể * là một sự khác biệt thực sự (tức là OP đã không thực hiện một lỗi thời gian), là nếu 'sstring' là NULL.Tiêu đề có thuộc tính 'Required', nghĩa là nó không phải là NULL. –

+0

@PanagiotisKanavos Bạn có chắc chắn rằng SQL Server sẽ sử dụng nhiều chỉ mục trong một truy vấn? –

+0

SQL Server sẽ sử dụng tùy chọn hiệu quả nhất. Tất nhiên nó sẽ, nếu điều này * là * tùy chọn rẻ nhất. Hoặc nó có thể quyết định cache kết quả tạm thời trong tempdb. Số liệu thống kê không hợp lệ hoặc chỉ mục bị thiếu mặc dù có nghĩa là nó có thể chọn sai gói vì nó không biết loại dữ liệu nào sẽ tìm thấy trong 'Tiêu đề'. Trong mọi trường hợp, hai phương pháp tiếp cận thậm chí không tương đương - cách tiếp cận đầu tiên * sẽ * trả về nhiều lần các hàng đáp ứng nhiều hơn một điều kiện. Cách tiếp cận thứ hai sẽ lọc các hàng chống lại tất cả các điều kiện và trả lại chúng một lần –

1

Như tôi nói vấn đề có thể là trong chỉ số nếu bạn muốn truy vấn của bạn đi nhanh hơn với truy vấn chính xác này tôi đề nghị bạn tạo chỉ mục này:

CREATE NONCLUSTERED INDEX PartIndex 
ON Part (PartID, Manufacturer_Number, Part_Number, Title) 

Đừng quên cập nhật thống kê nếu bạn thay đổi bảng của bạn dữ liệu rất nhiều.

+2

Part_Number và Manufacturer_Number đã được lập chỉ mục. Các thuộc tính có thuộc tính 'Index'. Đó là thuộc tính 'Title' không có chỉ mục. Người ta sẽ mong đợi cả hai nỗ lực để mất cùng một thời gian vì điều đó. OP nên đăng các truy vấn được tạo ra –

+0

@PanagiotisKanavos đồng ý, chúng ta hãy chờ đợi cho anh ta –

+0

Helpfully, SQL Server theo dõi các chỉ mục mà bạn * không * có và điều đó sẽ tạo ra sự khác biệt. Dưới đây là một số tập lệnh sẽ cho bạn biết bạn có thể thêm chỉ mục nào, điều này sẽ mang lại những cải thiện hiệu suất tốt nhất: http://mikesknowledgebase.com/pages/SQLServer/FindingMissingIndexes.htm –

Các vấn đề liên quan