2012-01-04 29 views
5

Tôi đang sử dụng SQLite trong ứng dụng iOS của mình và tôi có rất nhiều lưu/tải để thực hiện trong khi người dùng tương tác với giao diện người dùng. Đây là một vấn đề vì nó làm cho giao diện người dùng rất háo hức và chậm chạp.Hiệu suất làm chậm SQLite của iOS

Tôi đã thử thực hiện các thao tác trong một chuỗi bổ sung nhưng tôi không nghĩ rằng điều này là có thể trong SQLite. Tôi nhận được các mã lỗi SQLITE_BUSY và SQLITE_LOCKED thường xuyên nếu tôi làm điều đó.

Có cách nào để làm điều này trong đa luồng mà không có các mã lỗi đó hay tôi nên từ bỏ SQLite?

+1

Bạn đã thử điều chỉnh các truy vấn bạn sử dụng và xem các kế hoạch truy vấn để xem liệu có cần chỉ mục nào không? –

+2

Bạn có đang sử dụng các giao dịch khi thực hiện nhiều lần ghi không? Bạn nên - nó tạo ra một sự khác biệt rất lớn. –

+0

Frederick Cheung: Tôi đang sử dụng nhiều tính năng ghi và truy xuất. Tôi sẽ xem xét xem liệu lập chỉ mục có giúp ích hay không, nhưng có rất nhiều bản ghi để chèn nên tôi không nghĩ rằng việc lập chỉ mục sẽ giúp ích. Licks nóng: Tôi không thực hiện giao dịch khi sử dụng nhiều lần viết. Tôi có nên làm điều này cho mỗi viết trong cơ sở dữ liệu bằng cách sử dụng cùng một khóa? – VTS12

Trả lời

0

Đừng từ bỏ SQLite. Bạn chắc chắn có thể làm điều đó trong một chủ đề khác với chủ đề UI để tránh sự chậm trễ. Chỉ cần đảm bảo chỉ một chuỗi đang truy cập vào cơ sở dữ liệu tại một thời điểm. SQLite không phải là tuyệt vời khi giao dịch với truy cập đồng thời.

+1

Nó tốt cho các _reads_ đồng thời, nhưng _updates_ khóa mọi thứ khác (do sự phức tạp của bất kỳ điều gì tốt hơn so với khóa cấp DB). –

+0

Vấn đề của tôi là tôi không thể kiểm soát khi người dùng truy cập/ghi dữ liệu. Ví dụ, trên một khung nhìn nó sẽ đọc và lưu dữ liệu, nhưng sau đó họ có thể nhấp vào chi tiết và đẩy một chế độ xem mới cũng sẽ muốn đọc/ghi dữ liệu. Không chắc chắn làm thế nào tôi có thể chắc chắn rằng một thread truy cập cơ sở dữ liệu cùng một lúc. – VTS12

3

Hoàn toàn có thể, bạn chỉ cần nối tiếp quyền truy cập vào SQLite trong chuỗi nền của bạn.

Câu trả lời của tôi trên this recent question sẽ chỉ cho bạn đúng hướng tôi nghĩ.

Như đã đề cập ở nơi khác, SQLite là tốt cho các lần đọc đồng thời, nhưng khóa ở cấp cơ sở dữ liệu để ghi. Điều đó có nghĩa là nếu bạn đang đọc và viết trong các chủ đề khác nhau, bạn sẽ nhận được các lỗi SQLITE_BUSY và SQLITE_LOCKED. Cách cơ bản nhất để tránh điều này là nối tiếp tất cả quyền truy cập DB (đọc và ghi) trong hàng đợi công văn hoặc NSOperationQueue có đồng thời là 1. Vì quyền truy cập này không diễn ra trên chuỗi chính , giao diện người dùng của bạn sẽ không bị ảnh hưởng.

Điều này rõ ràng sẽ ngừng đọc và viết chồng chéo, nhưng nó cũng sẽ dừng đọc đồng thời. Nó không rõ ràng cho dù đó là một hit hiệu suất mà bạn có thể có hay không.

Để khởi một hàng đợi như mô tả ở trên:

NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init]; 

[backgroundQueue setMaxConcurrentOperationCount:1]; 

Sau đó, bạn chỉ có thể thêm các hoạt động vào hàng đợi như bạn thấy phù hợp.

+0

Tôi đã thử làm theo cách này và vẫn gặp lỗi. Tôi hiện đang sử dụng hàng đợi công văn. – VTS12

+0

bây giờ bạn có mọi thứ hoạt động bình thường không? Một hàng đợi công văn cũng sẽ tốt. – paulbailey

+0

Không, sau khi sử dụng hàng đợi công văn, tôi liên tục nhận được mã lỗi SQLITE_BUSY và SQLITE_LOCKED. Ngoài ra hành vi kỳ lạ như quan điểm đang được popped sớm vv – VTS12

0

OFF:

Bạn đã kiểm: FMDB nó là một Wrapper sqlite và là chủ đề an toàn. Tôi đã sử dụng nó trong tất cả dự án sqlite của mình.

0

Tôi khuyên bạn nên sử dụng Dữ liệu cốt lõi nằm trên đầu trang của sqlite. Tôi sử dụng nó trong một môi trường đa luồng. Dưới đây là hướng dẫn về Concurrency with Core Data.

2

Có mọi thứ trong chuỗi chuyên đề SQLite hoặc hàng đợi hoạt động một lần trong một thời gian là giải pháp tuyệt vời, đặc biệt là để giải quyết giao diện người dùng của bạn. Một kỹ thuật khác (có thể không giúp jitters) là phát hiện ra các mã lỗi đó và chỉ cần lặp lại, thử lại bản cập nhật cho đến khi bạn nhận được mã trả về thành công.

1

Đặt SQLite vào chế độ WAL. Sau đó lần đọc sẽ không bị chặn. Không phải như vậy viết - bạn cần phải serialize chúng. Có nhiều cách khác nhau để đạt được nó. Một trong số chúng được cung cấp bởi SQLite - Móc treo có thể được sử dụng để báo hiệu rằng ghi tiếp theo có thể bắt đầu.

Chế độ WAL nói chung sẽ cải thiện hiệu suất của ứng dụng của bạn. Hầu hết mọi thứ sẽ nhanh hơn một chút. Đọc sẽ không bị chặn chút nào. Chỉ các giao dịch lớn (vài MB) sẽ chậm lại. Nói chung không có gì ấn tượng.

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