2011-12-28 36 views
5

Tôi đang sử dụng django/apache/sqlite3 và tôi có một mô hình django trông như thế này:Cải thiện hiệu suất của django DB truy vấn

class Temp_entry(models.Model): 
    dateTime = models.IntegerField() #datetime 
    sensor = models.IntegerField() # id of sensor 
    temp = models.IntegerField()  # temp as temp in Kelvin * 100 

Tôi đang cố gắng để có được 300 Temp_entry mục cuối cùng để đặt vào một đồ thị. Tôi làm như vậy:

revOutsideTempHistory = Temp_entry.objects.filter(sensor=49).order_by('dateTime').reverse()[:300] 

Tuy nhiên, truy vấn này mất ~ 1 giây. đây có phải là cách cải thiện nó? Tôi đã đào xung quanh và thấy rằng order_by là khủng khiếp không hiệu quả, vì vậy tôi hy vọng rằng có một thay thế khả thi? Một thay thế tôi nghĩ, nhưng không thể tìm ra cách để thực hiện, sẽ chạy truy vấn sau mỗi 20 phút và giữ cho nó được lưu vào bộ nhớ cache, điều đó cũng có thể chấp nhận được, vì dữ liệu có thể hơi cũ và không bị bệnh hiệu ứng.

Trả lời

6

Nếu caching được chấp nhận, hãy luôn sử dụng nó. Một cái gì đó như:

from django.core.cache import cache 

cached = cache.get('temp_entries') 
if cached: 
    result = cached 
else: 
    result = Temp_entry.objects.filter(sensor=49).order_by('dateTime').reverse().values_list()[:300] 
    cache.set('temp_entries', result, 60*20) # 20 min 

Ngoài ra bạn có thể đặt db_indexes cho các cột thích hợp

class Temp_entry(models.Model): 
    dateTime = models.IntegerField(db_index=True) #datetime 
    sensor = models.IntegerField(db_index=True) # id of sensor 
    temp = models.IntegerField()  # temp as temp in Kelvin * 100 
+0

Cảm ơn Alexey, hai câu hỏi tiếp theo: có cách nào để truy vấn chạy 20 phút một lần thay vì đợi yêu cầu kiểm tra xem nó có cũ không? Db_indexes làm gì? – Andy

+1

Andy, db_index chỉ tạo chỉ mục cơ sở dữ liệu bình thường, sẽ làm tăng tốc độ truy vấn. Tuy nhiên, tốc độ này không là gì so với bộ nhớ đệm. Cũng lưu ý rằng các DB như Mysql và Postgre có bộ nhớ đệm nội bộ của các truy vấn, nhưng không chắc chắn về sqlite. Theo câu hỏi đầu tiên: có bạn có thể sử dụng lệnh django và một cái gì đó như cron hoặc cần tây nhưng tôi nghĩ rằng đây không phải là giải pháp tốt –

+0

Cảm ơn Alexey, bằng cách sử dụng các chỉ mục và bộ nhớ đệm xem là rendering trong một số tiền chấp nhận được thời gian – Andy

-1

Vâng, nếu bạn biết mục của bạn luôn luôn có một dateTime tăng (tức là datetime được thiết lập khi nhập cảnh được tạo ra và không chỉnh sửa), sau đó bạn không phải đặt hàng trước dateTime vì chúng sẽ tự nhiên theo thứ tự đó trong cơ sở dữ liệu.

2

Bạn có thể cần phải thêm một số chỉ mục khác trong cơ sở dữ liệu của mình. Sử dụng thanh công cụ django-debug để lấy SQL của truy vấn thực tế đang được chạy và sử dụng tính năng GIẢI THÍCH để hiển thị các chỉ mục mà nó đang sử dụng. Đối với truy vấn cụ thể này, tôi tưởng tượng bạn cần thêm chỉ mục trên (sensor, dateTime) - thực hiện điều đó trực tiếp trong trình vỏ cơ sở dữ liệu.

+0

trong một bình luận trên thread này OP hỏi một câu hỏi về những gì một chỉ mục làm. Tôi nghĩ tôi sẽ chỉ ra điều đó cho bạn. – Droogans

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