2009-10-13 37 views
6

Tôi đã từng đùa giỡn với việc chuyển từ các tệp truy cập ms sang tệp SQLite cho các nhu cầu cơ sở dữ liệu đơn giản của tôi; vì các lý do thông thường: kích thước tệp nhỏ hơn, chi phí thấp hơn, nguồn mở, v.v.Cách tăng tốc truy vấn với nhiều INNER JOIN

Một điều ngăn cản tôi thực hiện chuyển đổi là điều thiếu tốc độ trong SQLite. Đối với các truy vấn SELECT đơn giản, SQLite có vẻ hoạt động tốt, hoặc tốt hơn so với MS-Access. Vấn đề xảy ra với truy vấn SELECT khá phức tạp với nhiều câu lệnh INNER JOIN:

SELECT DISTINCT 
     DESCRIPTIONS.[oCode] AS OptionCode, 
     DESCRIPTIONS.[descShort] AS OptionDescription 
FROM DESCRIPTIONS 
INNER JOIN tbl_D_E ON DESCRIPTIONS.[oCode] = tbl_D_E.[D] 
INNER JOIN tbl_D_F ON DESCRIPTIONS.[oCode] = tbl_D_F.[D] 
INNER JOIN tbl_D_H ON DESCRIPTIONS.[oCode] = tbl_D_H.[D] 
INNER JOIN tbl_D_J ON DESCRIPTIONS.[oCode] = tbl_D_J.[D] 
INNER JOIN tbl_D_T ON DESCRIPTIONS.[oCode] = tbl_D_T.[D] 
INNER JOIN tbl_Y_D ON DESCRIPTIONS.[oCode] = tbl_Y_D.[D] 
WHERE ((tbl_D_E.[E] LIKE '%') 
     AND (tbl_D_H.[oType] ='STANDARD') 
     AND (tbl_D_J.[oType] ='STANDARD') 
     AND (tbl_Y_D.[Y] = '41') 
     AND (tbl_Y_D.[oType] ='STANDARD') 
     AND (DESCRIPTIONS.[oMod]='D')) 

Trong truy cập MS, truy vấn này thực hiện trong khoảng 2,5 giây. Trong SQLite, phải mất hơn 8 phút. Phải mất cùng một lượng thời gian cho dù tôi đang chạy truy vấn từ mã VB hoặc từ dấu nhắc lệnh bằng cách sử dụng sqlite3.exe.

Vì vậy, câu hỏi của tôi như sau:

  1. là SQLite chỉ không được tối ưu hóa để xử lý nhiều lệnh INNER JOIN?
  2. Tôi đã làm điều gì đó rõ ràng là ngu ngốc trong truy vấn của mình (vì tôi mới sử dụng SQLite) khiến nó quá chậm?

trước khi bất kỳ ai đề xuất một công nghệ hoàn toàn khác, tôi không thể chuyển đổi. Lựa chọn của tôi là MS-Access hoặc SQLite. :)

CẬP NHẬT: Chỉ định một INDEX cho mỗi cột trong cơ sở dữ liệu SQLite giảm thời gian truy vấn từ trên 8 phút xuống còn khoảng 6 giây. Nhờ có Larry Lustig để giải thích lý do tại sao INDEXing là cần thiết.

+3

Bạn đang sử dụng INDEXES? –

+0

@Phill Pafford: Tôi không sử dụng các chỉ mục trên dữ liệu MS-Access hoặc SQLite. Tôi đang cố gắng để so sánh truy cập vào sqlite vì vậy tôi đã để lại cấu trúc dữ liệu giống nhau trong cả hai. – Stewbob

+9

Không thể đăng câu trả lời, vì vậy hãy thử nhận xét: MS Access rất tích cực về việc lập chỉ mục các cột thay mặt bạn, trong khi SQLite sẽ yêu cầu bạn tạo một cách rõ ràng các chỉ mục bạn cần. Vì vậy, có thể Access đã lập chỉ mục [Mô tả] hoặc [D] cho bạn nhưng các chỉ mục đó bị thiếu trong SQLite. Tôi không có kinh nghiệm với số lượng hoạt động JOIN đó trong SQLite. Tôi đã sử dụng nó trong một dự án Django với một lượng dữ liệu tương đối nhỏ và không phát hiện bất kỳ vấn đề hiệu suất nào. –

Trả lời

11

Theo yêu cầu, tôi reposting bình luận trước đây của tôi như một câu trả lời thực tế (khi tôi lần đầu tiên gửi nhận xét Tôi không thể, vì lý do nào đó, để đăng câu trả lời):

MS Access rất tích cực về việc lập chỉ mục các cột thay mặt bạn, trong khi SQLite sẽ yêu cầu bạn tạo một cách rõ ràng các chỉ mục bạn cần. Vì vậy, có thể Access đã lập chỉ mục [Mô tả] hoặc [D] cho bạn nhưng các chỉ mục đó bị thiếu trong SQLite. Tôi không có kinh nghiệm với số lượng hoạt động JOIN trong SQLite. Tôi đã sử dụng nó trong một dự án Django với một lượng dữ liệu tương đối nhỏ và không phát hiện bất kỳ vấn đề hiệu suất nào.

6

Bạn có vấn đề với tính toàn vẹn giới thiệu không? Tôi hỏi vì có ấn tượng bạn đã có không cần thiết tham gia, vì vậy tôi đã viết lại truy vấn của bạn như:

SELECT DISTINCT 
     t.[oCode] AS OptionCode, 
     t.[descShort] AS OptionDescription 
    FROM DESCRIPTIONS t 
    JOIN tbl_D_H h ON h.[D] = t.[oCode] 
       AND h.[oType] = 'STANDARD' 
    JOIN tbl_D_J j ON j.[D] = t.[oCode] 
       AND j.[oType] = 'STANDARD' 
    JOIN tbl_Y_D d ON d.[D] = t.[oCode] 
       AND d.[Y] = '41' 
       AND d.[oType] ='STANDARD' 
WHERE t.[oMod] = 'D' 
+0

@rexem: Cảm ơn bạn đã dọn dẹp phiên bản truy vấn. Tôi quay lại và nhìn vào truy vấn của mình, và hóa ra tôi đã bỏ qua một vài câu lệnh WHERE, vì vậy có, tôi cần tất cả các JOIN. Tôi vẫn học được một vài điều hữu ích từ câu trả lời của bạn. CẢM ƠN! – Stewbob

+0

Stewbob - nếu đây thực sự là câu trả lời, bạn nên đánh dấu nó như vậy để rexem được điểm. Anh ấy đưa vào một số công việc tốt để đưa ra giải pháp này! –

+0

@Mark: Theo nhận xét, Larry Lustig đã cung cấp câu trả lời nhưng chưa quay lại để đăng câu trả lời để nhận được tín dụng. –

0

Nếu DESCRIPTIONS và tbl_D_E có nhiều lần quét hàng thì oCode và D sẽ được lập chỉ mục. Xem ví dụ ở đây để xem cách lập chỉ mục và cho biết có bao nhiêu lần quét hàng (http://www.siteconsortium.com/h/p1.php?id=mysql002).

này có thể khắc phục nó mặc dù ..

CREATE INDEX ocode_index VỀ MÔ TẢ (oCode) SỬ DỤNG BTREE; TẠO INDEX d_index TRÊN tbl_D_E (D) SỬ DỤNG BTREE;

vv ....

Lập chỉ mục chính xác là một phần của câu đố có thể dễ dàng tăng gấp đôi, gấp ba lần tốc độ truy vấn.

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