我有两个查询集,它收集了相同的结果,但我使用不同的方法来查看特定年份的特定月份。
在第一种情况下,我使用整个日期本身和'01'的日期,在第二种情况下,我使用BETWEEN
来选择年份和EXTRACT
这个月。
在我的第一个场景中,查询集需要超过2百万才能执行,而在第二种情况下,查询集几乎立即执行。
这里是相关查询:
第一个案例
SELECT [lot of fields]
FROM "dsn_consolidationcontrat"
INNER JOIN "dsn_consolidationindividu" ON ("dsn_consolidationcontrat"."individu_id" = "dsn_consolidationindividu"."id")
INNER JOIN "dsn_consolidationetablissement" ON ("dsn_consolidationcontrat"."etablissement_id" = "dsn_consolidationetablissement"."id")
INNER JOIN "dsn_consolidationentreprise" ON ("dsn_consolidationetablissement"."entreprise_id" = "dsn_consolidationentreprise"."id")
LEFT OUTER JOIN "dsn_consolidationcontrat" T5 ON ("dsn_consolidationcontrat"."contrat_precedent_id" = T5."id")
LEFT OUTER JOIN "dsn_consolidationcontratfin" ON ("dsn_consolidationcontrat"."id" = "dsn_consolidationcontratfin"."contrat_id")
WHERE ("dsn_consolidationcontrat"."id" IN (
SELECT U0."consolide_id" FROM "dsn_historiquecontrat" U0
INNER JOIN "dsn_declaration" U1 ON (U0."declaration_courante_id" = U1."id")
WHERE U1."mois" = '2016-12-01'::date)
AND NOT ("dsn_consolidationcontrat"."id" IN (
SELECT U2."contrat_id" FROM "dsn_historiquecontratfin" U0
INNER JOIN "dsn_declaration" U1 ON (U0."declaration_courante_id" = U1."id")
INNER JOIN "dsn_consolidationcontratfin" U2 ON (U0."consolide_id" = U2."id")
WHERE U1."mois" = '2016-12-01'::date))
AND NOT ("dsn_consolidationcontrat"."id" IN (
SELECT U0."consolide_id" FROM "dsn_historiquecontrat" U0
INNER JOIN "dsn_declaration" U1 ON (U0."declaration_courante_id" = U1."id")
WHERE (U1."mois" = '2017-01-01'::date AND U0."declaration_precedente_id" IS NOT NULL))))
LIMIT 10
第二个案例
SELECT [lot of fields]
FROM "dsn_consolidationcontrat"
INNER JOIN "dsn_consolidationindividu" ON ("dsn_consolidationcontrat"."individu_id" = "dsn_consolidationindividu"."id")
INNER JOIN "dsn_consolidationetablissement" ON ("dsn_consolidationcontrat"."etablissement_id" = "dsn_consolidationetablissement"."id")
INNER JOIN "dsn_consolidationentreprise" ON ("dsn_consolidationetablissement"."entreprise_id" = "dsn_consolidationentreprise"."id")
LEFT OUTER JOIN "dsn_consolidationcontrat" T5 ON ("dsn_consolidationcontrat"."contrat_precedent_id" = T5."id")
LEFT OUTER JOIN "dsn_consolidationcontratfin" ON ("dsn_consolidationcontrat"."id" = "dsn_consolidationcontratfin"."contrat_id")
WHERE ("dsn_consolidationcontrat"."id" IN (
SELECT U0."consolide_id" FROM "dsn_historiquecontrat" U0
INNER JOIN "dsn_declaration" U1 ON (U0."declaration_courante_id" = U1."id")
WHERE U1."mois" BETWEEN '2016-01-01'::date AND '2016-12-31'::date AND EXTRACT('month' FROM U1."mois") = 12))
AND NOT ("dsn_consolidationcontrat"."id" IN (
SELECT U2."contrat_id" FROM "dsn_historiquecontratfin" U0
INNER JOIN "dsn_declaration" U1 ON (U0."declaration_courante_id" = U1."id")
INNER JOIN "dsn_consolidationcontratfin" U2 ON (U0."consolide_id" = U2."id")
WHERE (U1."mois" BETWEEN '2016-01-01'::date AND '2016-12-31'::date AND EXTRACT('month' FROM U1."mois") = 12)))
AND NOT ("dsn_consolidationcontrat"."id" IN (
SELECT U0."consolide_id" FROM "dsn_historiquecontrat" U0
INNER JOIN "dsn_declaration" U1 ON (U0."declaration_courante_id" = U1."id")
WHERE (U1."mois" BETWEEN '2017-01-01'::date AND '2017-12-31'::date AND U0."declaration_precedente_id" IS NOT NULL AND EXTRACT('month' FROM U1."mois") = 1))))
LIMIT 10
两个查询集的执行计划彼此非常不同:在第一种情况下,我们得到了一堆散列连接,后跟独特的操作,但在第二种情况下,我们有一个漂亮的嵌套循环序列。
感谢您的任何解释。