2012-07-10 33 views
8

Tôi cần tìm nạp một số dữ liệu dựa trên từ khóa, truy vấn được kiểm tra chính xác 100%, nhưng sự cố là tải của reader là khá chậm. Tôi đã thử thay thế truy vấn này bằng truy vấn không chứa inner join và tải khá nhanh. Vì vậy, tôi tự hỏi, vì tôi chỉ chọn một cột là kết quả, tại sao DataTable.Load() mất quá nhiều thời gian? Có phải ExecuteReader của SQLite tải toàn bộ kết quả chứ không phải chỉ một cột không?Tải trình đọc dữ liệu rất chậm

Trước khi sử dụng DataTable, thời gian thực hiện trung bình mỗi reader.Read() là 7 giây.

Đây là mã của tôi:

_database.Connect(); 

var selectCommand = new SQLiteCommand(
@"SELECT A.ID AS MY_ID FROM MD 
INNER JOIN TMD ON MD.ID = TMD.ID_MD 
INNER JOIN TR ON TR.ID = TMD.ID_TR 
INNER JOIN P ON P.ID = TR.ID_P 
INNER JOIN DP ON DP.ID_P = P.ID 
INNER JOIN CD ON CD.ID = DP.ID_CD 
WHERE CD.DESC = @desc" 
); 

selectCommand.Parameters.AddWithValue("@desc", value); 

using (DbDataReader reader = _database.ExecuteQuery(selectCommand)) 
{ 
    DataTable data = new DataTable("MyData"); 
    data.Load(reader); 
} 
_database.Disconnect(); 
+1

Có vẻ như truy vấn của bạn chỉ đơn giản là chậm. Có cách nào khác để truy cập các bảng của bạn sao cho bạn không phải thực hiện quá nhiều lần tham gia? – Tejs

+0

Tôi biết điều này sẽ bị tổn thương .. Thật không may, chúng tôi cần kết nối 2 bảng dựa trên một trong các trường. Các phép nối này là kết nối duy nhất giữa chúng, với lược đồ DB hiện tại. – iCantSeeSharp

+0

'_database' là gì và tại sao có các phương thức như' Connect' và 'Disconnect'? Đừng sáng tạo lại bánh xe. Bạn cũng nên sử dụng 'using-statement' cho kết nối của bạn để đảm bảo rằng nó được" đóng "càng sớm càng tốt. Đây có phải là môi trường đa luồng như ASP.NET không? –

Trả lời

2

The SQLite Query Planner cung cấp một số gợi ý về tối ưu hóa truy vấn cho SQLite.

Một số mặt hàng có thể áp dụng cho câu hỏi của bạn:

1.) Do việc thực hiện trong SQLite bạn có thể cố gắng sắp xếp lại các nhiều tham gia:

Việc thực hiện hiện tại của SQLite chỉ sử dụng nối vòng lặp. Đó là để nói, tham gia được thực hiện như vòng lặp lồng nhau. Thứ tự mặc định của các vòng lặp lồng nhau trong một phép nối là cho bảng ngoài cùng bên trái trong mệnh đề FROM để tạo thành vòng ngoài và bảng bên phải để tạo thành vòng lặp bên trong.

Vì vậy, tùy thuộc vào cách JOIN được xây dựng có thể có sự khác biệt về hiệu suất.

SQLite cố gắng tối ưu hóa này tự động, nhưng như xa như tôi hiểu các tài liệu không có đảm bảo cho sự thành công (nổi bật của tôi):

Tuy nhiên, SQLite sẽ tổ các vòng theo một thứ tự khác nhau nếu làm do đó, sẽ giúp nó chọn các chỉ mục tốt hơn. [...] Tham gia sắp xếp lại là tự động và thường hoạt động đủ tốt để các lập trình viên không phải suy nghĩ về điều đó, đặc biệt nếu ANALYZE đã được sử dụng để thu thập số liệu thống kê về các chỉ số có sẵn . Nhưng đôi khi một số gợi ý từ lập trình viên là cần thiết.

2.) Ngoài ra, xin lưu ý rằng bên tham gia được nội quy đổi ra mệnh đề WHERE, vì vậy bất kỳ của những lời khuyên hiệu quả trong WHERE phần của tài liệu có thể áp dụng, quá:

ON và mệnh đề SỬ DỤNG của một liên kết bên trong được chuyển đổi thành các điều khoản bổ sung của mệnh đề WHERE trước khi phân tích mệnh đề WHERE được mô tả ở trên trong đoạn 1.0. Vì vậy, với SQLite, không có lợi thế tính toán để sử dụng cú pháp nối SQL92 mới hơn so với cú pháp kết nối dấu phẩy SQL89 cũ hơn .Cả hai đều hoàn thành chính xác điều tương tự trên các kết nối bên trong.

3.) Bạn có thể cân nhắc để chọn cột hơn trong tuyên bố của bạn, nếu có bất kỳ chỉ số trên chúng:

Nó không phải là cần thiết cho mỗi cột của một chỉ số để xuất hiện trong một WHERE thuật ngữ điều khoản để chỉ mục đó được sử dụng. Nhưng có không thể là khoảng trống trong các cột của chỉ mục được sử dụng.

+0

Tất cả các kết nối được xây dựng trên các khóa chính, tôi nghĩ rằng điều này giải quyết được vấn đề về lập chỉ mục, nhưng tôi thực sự đang cố gắng nghĩ 1 nếu 2 có thể là trình bảo vệ cuộc sống cho trường hợp của tôi. – iCantSeeSharp

+0

Tôi đã sử dụng 'ANALYZE' trước lệnh sql của tôi và truy vấn được thực thi khá nhanh. Vì vậy, xem xét rằng bạn đã cung cấp hướng chính xác cho vấn đề cụ thể này, bạn sẽ nhận được câu trả lời. Cảm ơn! – iCantSeeSharp

3

Tôi nghĩ rằng điều này xảy ra do tính chất của SQLite và số lượng lớn các tham gia.

Cố gắng lập lại lược đồ cơ sở dữ liệu, như dữ liệu hóa chuẩn hóa để truy cập nhanh hơn.

+0

Liệu "bản chất của SQLite" có nghĩa là các kết quả mong đợi khác với kết quả hiện tại được trả về? – iCantSeeSharp

+0

@ Souvlaki: Tôi có nghĩa là SQLite không hỗ trợ tải trọng tốt cho số lượng tham gia như vậy, ngoài ra bạn cũng có thể có một tệp lớn làm giảm tính ổn định của kết quả. – abatishchev

+0

Mặc dù truy vấn khá nhanh trên Navicat? – iCantSeeSharp

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