在排序操作之前,EXPLAIN ANALYZE的输出是相同的,因此排序会有所不同。
在这两个查询中,您都返回的所有行
product_product,但在第一种情况下,您按的列进行排序
django_site,因此
django_site.domain必须另外检索,这会产生额外的费用。但是不会解释很大的区别。
行中的 物理顺序 很有可能
product_product已经根据列
ordering进行了排序,这使情况2的排序非常便宜,情况1的排序很昂贵。
后“更多的细节补充”:
这也是 相当昂贵 所以排序
charactervarying(100)不是排序的
integer列。除了整数要小得多之外,还有排序规则支持会使您放慢速度。要进行验证,请尝试通过订购
COLLATE"C"。在手册中阅读有关归类支持的更多信息。如果您
正在 运行PostgreSQL 9.1。我现在看到,您拥有PostgreSQL 8.4。
显然,查询输出中的所有行在上进行
django_site.domain过滤时都具有相同的值
p.site_id =1。如果查询计划者更聪明,则可能会跳过第一列以开始进行排序。
您运行PostgreSQL 8.4。9.1的查询计划器已经变得更加智能。升级可能会改变这种情况,但是我不能肯定地说。
为了验证我有关物理顺序的理论,您可以尝试使用随机插入的行制作大表的副本,然后再次运行查询。像这样:
CREATE TABLE p ASSELECt *FROM public.product_productORDER BY random();
接着:
EXPLAIN ANALYZESELECt p.*FROM pJOIN django_site d ON (p.site_id = d.id)WHERe p.activeAND p.site_id = 1ORDER BY d.domain, p.ordering, p.name;
有什么区别吗?->显然,这并不能解释…
OK,要测试是否
varchar(100)有所作为,我重新创建了您的方案。请参阅
单独的答案以及详细的测试用例和基准 。这个答案已经超载了。
总结一下:
事实证明,我的其他解释也很合适。速度下降的主要原因显然是
varchar(100)根据区域设置(
LC_COLLATE)按列排序。



