1

假設這是我的架構:許多一對多的關係 - 查詢性能與大表大小

class modelA(models.Model): 
    b = models.ManyToManyField(through='linkModel') 

class modelB(models.Model): 
    name = models.CharField() 

class linkModel(models.Models): 
    a = models.ForeignKey(modelA) 
    b = models.ForeignKey(modelB) 
    (other link-relevant stuff) 

在我能想到跑成的查詢性能問題,同時查找鏈接到B的情況下,什麼點A,反之亦然。 100,000行?百萬?

會使用單一的ForeignKey關係而不是ManyToMany(在某些情況下重新排列模式可能會)可以獲得更好的性能嗎?

回答

4

根據我不熟悉的框架行爲,可以將連接傳遞到後備數據庫服務器以供執行。如果是這種情況,那麼你會發現索引效率是O(log n),chokepoint不是連接,而是結果集的大小。

假設主管模式設計和索引,批量數據處理性能是總是門控的工作集的大小。

爲了獲得適用於您的數據庫服務器,框架和應用程序邏輯的特定組合的權威答案,您必須執行測試,與現代實踐一樣令人震驚。

您不一定需要以某種方式測試大型複雜應用程序。您可以將有趣的應用程序代碼摘錄到測試應用程序中。你雖然需要批量數據。

如果您希望有人已經測試過您的特定場景,那麼您將需要詳細描述您的配置。您已經提供了示例應用程序邏輯,這是一個良好的開端。

數量驚人的事情會干擾。例如,打開Microsoft SQL Server 2008數據庫上的自動縮小選項會產生巨大的開銷,並將TPM數字減少約3倍。您將不得不查找並記錄這些內容。

2

除了什麼Peter Wone said,這裏是應該在數據庫中存在兩個「方向」的JOIN到最佳執行「理想」的結表結構:

  • 有複合PK是一個組合的2 FKs。
  • 有一個替代索引是PK的確切「反向」。
  • 這兩個索引(主要和備用)都被壓縮,以最小化重複的前沿字段的開銷。
  • 沒有代理鍵(所以我們不需要第三個索引)。
  • clustered。由於備用索引已經包含了所有的PK字段(正好相反),因此在集羣表中不存在通常與備用索引關聯的開銷。並且由於它加入了JOIN,所以沒有雙重查詢。

對於甲骨文的語法是這樣的:

CREATE TABLE LINK_MODEL (
    MODEL_A_ID INT, 
    MODEL_B_ID INT, 
    PRIMARY KEY (MODEL_A_ID, MODEL_B_ID), 
    FOREIGN KEY (MODEL_A_ID) REFERENCES MODEL_A (MODEL_A_ID), 
    FOREIGN KEY (MODEL_B_ID) REFERENCES MODEL_B (MODEL_B_ID) 
) ORGANIZATION INDEX COMPRESS; 

CREATE INDEX LINK_MODEL_IE1 ON LINK_MODEL (MODEL_B_ID, MODEL_A_ID) COMPRESS; 

就這樣,查詢一個給定的A的燒烤需要只是那就是LINK_MODEL指數的簡單範圍掃描,沒有任何表堆訪問(根本沒有表堆)。查詢給定的B將需要在LINK_MODEL_IE1上進行簡單的範圍掃描,也不需要任何表堆訪問。

不幸的是,並不是所有的數據庫都支持集羣和索引壓縮,但是您應該儘可能多地實現您的DBMS和您的ORM允許的。