T
Thallius
Guest
Hi,
folgende Tabellen:
Foreign Keys und Indexe lass ich mal weg.
Eine Order kann mehrere Tools haben. Jedes Tool kann zu anderen Zeiten verschickt und zurück geschickt werden. Wichtig ist nur, das alle Tools in dem Zeitraum der Order vor Ort sind. Initial sind deliver_date und return_date NULL.
Daraus ergibt sich für die Order folgende Kombinationen die ich mal Status nenne:
deleted = 1 => "Deleted"
deliver_date = NULL und return_date = NULL => "Planned"
deliver_date != NULL und return_date = NULL => "In Execution"
deliver date != NULL und return_date != NULL => "Done"
Wenn ich nun eine liste der jobs mit ihrem Status haben will, fällt mir im Moment nur folgendes ein:
dessen explain folgendes ergibt (Logischerweise aber der vollständigkeit halber will ich es erwähnen)
Leider ist das bei 20000 Aufträgen doch recht langsam. Jemand einen Vorschlag wie man es schneller bekommt?
Gruß
Thallius
folgende Tabellen:
Code:
CREATE TABLE "public"."orders" (
"id" int4 NOT NULL DEFAULT nextval('order_id_seq'::regclass),
"type" varchar(255) NOT NULL,
"start_date" date NOT NULL,
"end_date" date NOT NULL,
"deleted" int2 DEFAULT 0
)
CREATE TABLE "public"."order_tools" (
"order_id" int4 NOT NULL,
"tool_number" varchar(50) NOT NULL,
"deliver_date" date default NULL,
"return_date" date default NULL,
)
Foreign Keys und Indexe lass ich mal weg.
Eine Order kann mehrere Tools haben. Jedes Tool kann zu anderen Zeiten verschickt und zurück geschickt werden. Wichtig ist nur, das alle Tools in dem Zeitraum der Order vor Ort sind. Initial sind deliver_date und return_date NULL.
Daraus ergibt sich für die Order folgende Kombinationen die ich mal Status nenne:
deleted = 1 => "Deleted"
deliver_date = NULL und return_date = NULL => "Planned"
deliver_date != NULL und return_date = NULL => "In Execution"
deliver date != NULL und return_date != NULL => "Done"
Wenn ich nun eine liste der jobs mit ihrem Status haben will, fällt mir im Moment nur folgendes ein:
Code:
SELECT id, type, job_type AS jobType, start_date as startDate, end_date AS endDate,
CASE WHEN deleted = 1 THEN 'deleted' ELSE
CASE WHEN
(
SELECT COUNT(ot1.order_id)
FROM order_tools ot1
WHERE ot1.order_id = o.id
AND ot1.deliver_date IS NOT NULL
) = 0
THEN 'planned'
ELSE
CASE WHEN
(
SELECT COUNT(ot2.order_id)
FROM order_tools ot2
WHERE ot2.order_id = o.id
AND ot2.return_date IS NULL
) <> 0
THEN 'executing'
ELSE 'done'
END
END
END AS status
FROM orders o
dessen explain folgendes ergibt (Logischerweise aber der vollständigkeit halber will ich es erwähnen)
Code:
Seq Scan on orders o (cost=0.00..3989021.25 rows=8807 width=91)
SubPlan 1
-> Aggregate (cost=226.43..226.44 rows=1 width=8)
-> Seq Scan on order_tools ot1 (cost=0.00..226.43 rows=1 width=4)
Filter: ((deliver_date IS NOT NULL) AND (order_id = o.id))
SubPlan 2
-> Aggregate (cost=226.43..226.44 rows=1 width=8)
-> Seq Scan on order_tools ot2 (cost=0.00..226.43 rows=1 width=4)
Filter: ((return_date IS NULL) AND (order_id = o.id))
Leider ist das bei 20000 Aufträgen doch recht langsam. Jemand einen Vorschlag wie man es schneller bekommt?
Gruß
Thallius