![](/img/trans.png)
[英]Sklearn StackingClassifier very slow and inconsistent cpu usage
[英]Usage of Subquery very slow
我有以下查詢,但需要大約 1:20 分鍾才能完成:
user_total_revenue = (
User.objects.annotate(
total_revenue=Sum("payments__amount"),
first_order_date=Subquery(
User.objects.filter(pk=OuterRef("pk"))
.annotate(first_order_date=Min("shops__orders__created"))
.values("first_order_date"),
output_field=DateTimeField(),
),
)
)
原始 SQL 查詢:
SELECT
"users_user"."id",
"users_user"."created",
"users_user"."updated",
"users_user"."user_id",
"users_user"."name",
"users_user"."address",
SUM("payments_payment"."amount") AS "total_revenue",
(
SELECT
MIN(U2."created") AS "first_order_date"
FROM
"users_user" U0
LEFT OUTER JOIN
"shops_shop" U1
ON (U0."id" = U1."user_id")
LEFT OUTER JOIN
"orders_order" U2
ON (U1."id" = U2."shop_id")
WHERE
U0."id" =
(
"users_user"."id"
)
GROUP BY
U0."id"
)
AS "first_order_date"
FROM
"users_user"
LEFT OUTER JOIN
"payments_payment"
ON ("users_user"."id" = "payments_payment"."user_id")
GROUP BY
"users_user"."id",
(
SELECT
MIN(U2."created") AS "first_order_date"
FROM
"users_user" U0
LEFT OUTER JOIN
"shops_shop" U1
ON (U0."id" = U1."user_id")
LEFT OUTER JOIN
"orders_order" U2
ON (U1."id" = U2."shop_id")
WHERE
U0."id" =
(
"users_user"."id"
)
GROUP BY
U0."id"
)
LIMIT 21
因為它太慢了,所以我用不同的方式寫了它,速度要快得多(< 1 秒):
def user_total_revenue():
first_orders = (
User.objects.annotate(first_order_date=Min("shops__orders__created"))
.values("pk", "first_order_date")
)
first_orders = {
item["pk"]: item["first_order_date"] for item in first_orders
}
user_total_revenue = User.objects.annotate(total_revenue=Sum("payments__amount"))
return [
{
"user": user,
"first_order_date": first_orders[user.pk],
}
for user in user_total_revenue
]
我想了解為什么我的第一個版本使用子查詢如此緩慢。
這里不是 100%,但我相信由此產生的查詢應該更快。
from django.db.models.functions import Coalesce
from django.db.models import Value
user_total_revenue = User.objects.annotate(
total_revenue=Coalesce(
Subquery(
Payment.object.filter(user_id=OuterRef("pk"))
.values("user_id")
.annotate(sum=Sum("amount"))
.values("sum")[:1]
),
Value(0),
),
first_order_date=Subquery(
User.objects.filter(pk=OuterRef("pk"))
.annotate(first_order_date=Min("shops__orders__created"))
.values("first_order_date"),
output_field=DateTimeField(),
),
)
其他嘗試:
使用order_by("shops__orders__created")
並選擇第一個項目而不是Min
添加索引以created
訂單
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.