我有一個具有以下索引的 django 模型:
class Meta:
indexes = [
models.Index(fields=['-current']),
models.Index(fields=['current']),
]
相關欄位定義為:
current = models.IntegerField(null=True)
添加了這些,我運行了遷移并看到了結果:
companies/migrations/0294_auto_20220110_1155.py
- Create index companies_c_current_f2c815_idx on field(s) -current of model company
- Create index companies_c_current_c8bcb7_idx on field(s) current of model company
我發現使用 ordering=current 運行 django-rest-framework 查詢比使用 ordering=-current 快約 5 倍。使用 PSQL 解釋我得到以下資訊:
# explain analyze select * from company order by current desc nulls last limit 100;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=41028.75..41040.42 rows=100 width=1223) (actual time=866.587..867.650 rows=100 loops=1) -> Gather Merge (cost=41028.75..68747.19 rows=237570 width=1223) (actual time=866.585..867.644 rows=100 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Sort (cost=40028.73..40325.69 rows=118785 width=1223) (actual time=849.292..849.296 rows=48 loops=3)
Sort Key: current DESC NULLS LAST
Sort Method: top-N heapsort Memory: 275kB
Worker 0: Sort Method: top-N heapsort Memory: 314kB
Worker 1: Sort Method: top-N heapsort Memory: 299kB
-> Parallel Seq Scan on companies_company (cost=0.00..35488.85 rows=118785 width=1223) (actual time=0.278..756.498 rows=95028 loops=3)
Planning Time: 0.444 ms
Execution Time: 867.759 ms
(12 rows)
# explain analyze select * from company order by current asc nulls last limit 100;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.42..49.79 rows=100 width=1223) (actual time=1.700..13.268 rows=100 loops=1)
-> Index Scan Backward using companies_c_current_f2c815_idx on companies_company (cost=0.42..140727.06 rows=285084 width=1223) (actual time=1.698..13.244 rows=100 loops=1)
Planning Time: 1.139 ms
Execution Time: 13.426 ms
(4 rows)
從上面可以清楚地看出,asc 使用的是索引,而 desc 沒有使用,這就解釋了時間差異。我的問題是:為什么不呢?是否需要以不同的方式添加索引以確保它同時用于 asc 和 desc?我最初嘗試將其添加到模型欄位定義中,db_index=True但產生了同樣的問題。
uj5u.com熱心網友回復:
可以雙向掃描索引,但它需要完全按照ORDER BY默認情況下的子句進行排序。普通索引按ASC NULLS LAST順序排序,因此它可以支持該順序或相反的順序,即DESC NULLS FIRST. 要創建可以支持您的ORDER BY子句的索引,請使用
CREATE INDEX ON companies_company (current ASC NULLS FIRST);
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/408986.html
標籤:
上一篇:嘗試在postgresql中運行相同的查詢時,SQLite查詢不起作用
下一篇:添加連接并在列中搜索任何字串
