M'dziko losamvetsetseka, olemba ntchito ayenera kugawidwa mofanana pakati pa antchito onse a bungwe lathu, koma zenizeni ntchito zimabwera, monga lamulo, kuchokera kwa anthu ochepa - "kuchokera kwa oyang'anira" kapena "kuchokera kwa ma contract ang'onoang'ono" ochokera kumadipatimenti oyandikana nawo (openda, okonza mapulani, otsatsa, ...).
Tiyeni tivomereze kuti m'gulu lathu la anthu 1000, olemba 20 okha (nthawi zambiri ngakhale ochepera) amayika ntchito kwa woimba aliyense komanso Tiyeni tigwiritse ntchito chidziwitso cha phunzirolikufulumizitsa funso "zachikhalidwe".
Script jenereta
-- ΡΠΎΡΡΡΠ΄Π½ΠΈΠΊΠΈ
CREATE TABLE person AS
SELECT
id
, repeat(chr(ascii('a') + (id % 26)), (id % 32) + 1) "name"
, '2000-01-01'::date - (random() * 1e4)::integer birth_date
FROM
generate_series(1, 1000) id;
ALTER TABLE person ADD PRIMARY KEY(id);
-- Π·Π°Π΄Π°ΡΠΈ Ρ ΡΠΊΠ°Π·Π°Π½Π½ΡΠΌ ΡΠ°ΡΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ΠΌ
CREATE TABLE task AS
WITH aid AS (
SELECT
id
, array_agg((random() * 999)::integer + 1) aids
FROM
generate_series(1, 1000) id
, generate_series(1, 20)
GROUP BY
1
)
SELECT
*
FROM
(
SELECT
id
, '2020-01-01'::date - (random() * 1e3)::integer task_date
, (random() * 999)::integer + 1 owner_id
FROM
generate_series(1, 100000) id
) T
, LATERAL(
SELECT
aids[(random() * (array_length(aids, 1) - 1))::integer + 1] author_id
FROM
aid
WHERE
id = T.owner_id
LIMIT 1
) a;
ALTER TABLE task ADD PRIMARY KEY(id);
CREATE INDEX ON task(owner_id, task_date);
CREATE INDEX ON task(author_id);
Tiyeni tiwonetse ntchito 100 zomaliza za wotsogolera wina:
SELECT
task.*
, person.name
FROM
task
LEFT JOIN
person
ON person.id = task.author_id
WHERE
owner_id = 777
ORDER BY
task_date DESC
LIMIT 100;
Timangofunika kuyika ID ya wolemba ndi dzina lake mumtanthauzira mawu kuti titha kuchotsa pogwiritsa ntchito kiyi iyi:
-- ΡΠΎΡΠΌΠΈΡΡΠ΅ΠΌ ΡΠ΅Π»Π΅Π²ΡΡ Π²ΡΠ±ΠΎΡΠΊΡ
WITH T AS (
SELECT
*
FROM
task
WHERE
owner_id = 777
ORDER BY
task_date DESC
LIMIT 100
)
-- ΡΠΎΡΠΌΠΈΡΡΠ΅ΠΌ ΡΠ»ΠΎΠ²Π°ΡΡ Π΄Π»Ρ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ
, dict AS (
SELECT
hstore( -- hstore(keys::text[], values::text[])
array_agg(id)::text[]
, array_agg(name)::text[]
)
FROM
person
WHERE
id = ANY(ARRAY(
SELECT DISTINCT
author_id
FROM
T
))
)
-- ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΠ²ΡΠ·Π°Π½Π½ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΠ»ΠΎΠ²Π°ΡΡ
SELECT
*
, (TABLE dict) -> author_id::text -- hstore -> key
FROM
T;
Koma bwanji ngati sitiyenera kusunga gawo limodzi lokha, koma zolemba zonse mumtanthauzira mawu? Pankhaniyi, kuthekera kwa PostgreSQL kudzatithandiza sungani cholembera patebulo ngati mtengo umodzi:
...
, dict AS (
SELECT
hstore(
array_agg(id)::text[]
, array_agg(p)::text[] -- ΠΌΠ°Π³ΠΈΡ #1
)
FROM
person p
WHERE
...
)
SELECT
*
, (((TABLE dict) -> author_id::text)::person).* -- ΠΌΠ°Π³ΠΈΡ #2
FROM
T;
Tiyeni tiwone zomwe zinali kuchitika apa:
Tinatenga p ngati dzina lolowera patebulo la munthu wathunthu nasonkhanitsa unyinji wa iwo.
izi zojambulira zidasinthidwanso ku mndandanda wa zingwe zolembedwa (munthu[]::malemba[]) kuti aziyika mu dikishonale ya hstore ngati mndandanda wamakhalidwe.
Tikalandira mbiri yokhudzana ndi izi, ife kutulutsa mtanthauzira mawu ndi kiyi ngati chingwe cholemba.
Tikufuna malemba sinthani kukhala mtengo wamtundu wa tebulo munthu (pa tebulo lililonse mtundu wa dzina lomwelo limapangidwa zokha).
WITH dict AS (
SELECT
hstore(
array_agg(i::text)
, array_agg(i::text)
)
FROM
generate_series(1, ...) i
)
TABLE dict;
Script yowunika: serialization
WITH T AS (
SELECT
*
, (
SELECT
regexp_replace(ea[array_length(ea, 1)], '^Execution Time: (d+.d+) ms$', '1')::real et
FROM
(
SELECT
array_agg(el) ea
FROM
dblink('port= ' || current_setting('port') || ' dbname=' || current_database(), $$
explain analyze
WITH dict AS (
SELECT
hstore(
array_agg(i::text)
, array_agg(i::text)
)
FROM
generate_series(1, $$ || (1 << v) || $$) i
)
TABLE dict
$$) T(el text)
) T
) et
FROM
generate_series(0, 19) v
, LATERAL generate_series(1, 7) i
ORDER BY
1, 2
)
SELECT
v
, avg(et)::numeric(32,3)
FROM
T
GROUP BY
1
ORDER BY
1;
Pa PostgreSQL 11, mpaka pafupifupi kukula kwa mtanthauzira mawu wa 2^12 makiyi kusindikiza ku json kumatenga nthawi yochepa. Pankhaniyi, chothandiza kwambiri ndi kuphatikiza kwa json_object ndi kutembenuka kwa mtundu wa "mkati". array_agg(i::text).
WITH T AS (
SELECT
*
, (
SELECT
regexp_replace(ea[array_length(ea, 1)], '^Execution Time: (d+.d+) ms$', '1')::real et
FROM
(
SELECT
array_agg(el) ea
FROM
dblink('port= ' || current_setting('port') || ' dbname=' || current_database(), $$
explain analyze
WITH dict AS (
SELECT
json_object(
array_agg(i::text)
, array_agg(i::text)
)
FROM
generate_series(1, $$ || (1 << v) || $$) i
)
SELECT
(TABLE dict) -> (i % ($$ || (1 << v) || $$) + 1)::text
FROM
generate_series(1, $$ || (1 << (v + 3)) || $$) i
$$) T(el text)
) T
) et
FROM
generate_series(0, 19) v
, LATERAL generate_series(1, 7) i
ORDER BY
1, 2
)
SELECT
v
, avg(et)::numeric(32,3)
FROM
T
GROUP BY
1
ORDER BY
1;
Ndipo ... kale pafupifupi ndi 2^6 makiyi, kuwerenga kuchokera mu dikishonale ya json kumayamba kutaya kangapo kuwerenga kuchokera ku hstore, chifukwa jsonb zomwezo zimachitika pa 2^9.
Zotsatira zomaliza:
ngati muyenera kuchita LOWANI ndi zolemba zambiri zobwereza - Ndi bwino kugwiritsa ntchito "dictionary" ya tebulo