假设这是我的架构:
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)
在查找链接到A的B实例时,我可以在什么时候遇到查询性能问题,反之亦然。 10万行?百万?
使用单个ForeignKey关系而不是ManyToMany(在某些情况下可能重新排列模式)会提供更好的性能吗?
答案 0 :(得分:4)
根据您不熟悉的框架行为,可以将连接传递给后备数据库服务器以供执行。如果是这种情况,那么你会发现索引效率是O(log n)而且阻塞点不是连接而是结果集的大小。
假设有能力的架构设计和索引,批量数据操作性能始终按工作集的大小进行门控。
要获得适用于您的数据库服务器,框架和应用程序逻辑的特定组合的明确答案,您将不得不执行测试,因为这可能与现代实践步调一致。
您不一定需要使用大型复杂应用程序进行测试。您可以将有趣的应用程序代码摘录到测试应用程序中。您将需要批量数据。
如果您希望某人已经测试过您的特定方案,那么您需要详细描述您的配置。您已经提供了示例应用程序逻辑,这是一个良好的开端。
令人惊讶的事情可能会干扰。例如,在Microsoft SQL Server 2008数据库上启用“自动缩小”选项会产生巨大的开销,并将TPM数字减少大约3倍。您必须查找并记录这些内容。
答案 1 :(得分:2)
除了Peter Wone said之外,这里还有“理想的”联结表结构,数据库中应该存在JOIN的“方向”以便最佳地执行:
Oracle的语法如下所示:
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的Bs只需要对LINK_MODEL
的索引进行简单的范围扫描,而不需要任何表堆访问(根本没有表堆)。查询给定的B将需要LINK_MODEL_IE1
上的简单范围扫描,也不需要任何表堆访问。
不幸的是,并非所有数据库都支持群集和索引压缩,但您应该像DBMS一样实现这一点,而ORM允许您这样做。