Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed May 19, 2021
2 parents 7c15000 + f28532f commit 8abcf32
Show file tree
Hide file tree
Showing 42 changed files with 1,361 additions and 711 deletions.
Expand Up @@ -31,20 +31,20 @@ public class ModifyObjectResult<T extends ObjectType> {

private final PrismObject<T> objectBefore;
private final PrismObject<T> objectAfter;
private final Collection<? extends ItemDelta> modifications;
private final Collection<? extends ItemDelta<?, ?>> modifications;

/**
* Performance record for the current operation.
* Very experimental. Probably should be present also for other repository operation result objects.
*/
private OperationRecord performanceRecord;

public ModifyObjectResult(Collection<? extends ItemDelta> modifications) {
public ModifyObjectResult(Collection<? extends ItemDelta<?, ?>> modifications) {
this(null, null, modifications);
}

public ModifyObjectResult(PrismObject<T> objectBefore, PrismObject<T> objectAfter,
Collection<? extends ItemDelta> modifications) {
Collection<? extends ItemDelta<?, ?>> modifications) {
this.objectBefore = objectBefore;
this.objectAfter = objectAfter;
this.modifications = modifications;
Expand All @@ -58,7 +58,7 @@ public PrismObject<T> getObjectAfter() {
return objectAfter;
}

public Collection<? extends ItemDelta> getModifications() {
public Collection<? extends ItemDelta<?, ?>> getModifications() {
return modifications;
}

Expand Down
Expand Up @@ -112,6 +112,7 @@ public interface RepositoryService {
String CLASS_NAME_WITH_DOT = RepositoryService.class.getName() + ".";

String OP_ADD_OBJECT = "addObject";
String OP_ADD_OBJECT_OVERWRITE = "addObjectOverwrite"; // addObject with overwrite option
String OP_DELETE_OBJECT = "deleteObject";
String OP_COUNT_OBJECTS = "countObjects";
String OP_MODIFY_OBJECT = "modifyObject";
Expand Down
@@ -1,25 +1,24 @@
/*
* Copyright (c) 2010-2019 Evolveum and contributors
* Copyright (C) 2010-2021 Evolveum and contributors
*
* This work is dual-licensed under the Apache License 2.0
* and European Union Public License. See LICENSE file for details.
*/

package com.evolveum.midpoint.repo.api.perf;

import java.util.Locale;

import com.evolveum.midpoint.util.ShortDumpable;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.xml.ns._public.common.common_3.RepositoryOperationPerformanceInformationType;

import java.util.Locale;

/**
* Experimental.
* Experimental.
*/
public class OperationPerformanceInformation implements ShortDumpable, Cloneable {

private int invocationCount;
private int executionCount;
private int executionCount; // counts each attempt, including retries
private long totalTime;
private Long minTime;
private Long maxTime;
Expand Down Expand Up @@ -105,7 +104,7 @@ public synchronized void shortDump(StringBuilder sb) {
sb.append(invocationCount);
sb.append(", total time: ").append(timeInfo(totalTime, minTime, maxTime, invocationCount));
if (totalTime > 0 && executionCount > invocationCount) {
sb.append(String.format(Locale.US, ", wasted time for %d retry/retries: %s (%s)", executionCount-invocationCount,
sb.append(String.format(Locale.US, ", wasted time for %d retry/retries: %s (%s)", executionCount - invocationCount,
timeInfo(totalWastedTime, minWastedTime, maxWastedTime, invocationCount), percent(totalWastedTime, totalTime)));
}
}
Expand Down
4 changes: 2 additions & 2 deletions repo/repo-sqale/README.adoc
Expand Up @@ -295,11 +295,11 @@ Insert performance measurements:

[source,sql]
----
INSERT INTO m_user (name_norm, name_orig, version)
INSERT INTO m_user (nameNorm, nameOrig, version)
VALUES ('user-' || LPAD(r::text, 10, '0'), 'user-' || LPAD(r::text, 10, '0'), 1);
----

Both name columns are indexed, `name_norm` is also unique.
Both name columns are indexed, `nameNorm` is also unique.
Loop is used to INSERT the rows, which is slower than `INSERT from SELECT` with `generate_series`,
but closer to real scenario that uses separate statements (although there are no round-trips here).

Expand Down
44 changes: 22 additions & 22 deletions repo/repo-sqale/sql/pg-org-experiments.sql
Expand Up @@ -46,15 +46,15 @@ with recursive org_h (
parent,
child
) as (
select r.targetoid, r.owner_oid from m_reference as r
select r.targetoid, r.ownerOid from m_reference as r
where r.reference_type = 0
-- this condition makes it super fast, the same out of CTE is much slower
and r.owner_oid = 'u7:21200-0...-....-....-............'
and r.ownerOid = 'u7:21200-0...-....-....-............'
union
select par.targetoid, chi.child
from m_reference as par, org_h as chi
where par.reference_type = 0
and par.owner_oid = chi.parent
and par.ownerOid = chi.parent
)
select distinct parent from org_h
-- select * from org_h
Expand All @@ -72,12 +72,12 @@ set jit = off;
-- generated by Querydsl
EXPLAIN (ANALYZE, VERBOSE, BUFFERS)
with recursive orgc (parent, child) as not materialized (
(select refpo.targetOid, refpo.owner_oid from m_ref_object_parent_org refpo)
(select refpo.targetOid, refpo.ownerOid from m_ref_object_parent_org refpo)
union
(select refpo.targetOid, orgc.child from m_ref_object_parent_org refpo, orgc orgc where refpo.owner_oid = orgc.parent)
(select refpo.targetOid, orgc.child from m_ref_object_parent_org refpo, orgc orgc where refpo.ownerOid = orgc.parent)
)
select po.name_orig, parent, child,
co.name_orig,
select po.nameOrig, parent, child,
co.nameOrig,
* from orgc
join m_object po on po.oid = parent
join m_object co on co.oid = child
Expand All @@ -93,7 +93,7 @@ select * from m_ref_object_parent_org;
CREATE OR REPLACE FUNCTION m_org_clsr(ancestorOid UUID)
RETURNS TABLE (
ancestor_oid UUID, -- ref.targetoid
descendant_oid UUID --ref.owner_oid
descendant_oid UUID --ref.ownerOid
)
LANGUAGE plpgsql
AS $$
Expand All @@ -117,40 +117,40 @@ order by oid;
-- using function m_org_clsr(ancestorOid): 1000 ms for oids, 1400 ms for full rows
-- using m_org_closure with rule: 23 s! no noticeable difference between oid/full select
select oid from m_user u
where u.name_norm like '%45'
where u.nameNorm like '%45'
and exists (select 1 from
m_ref_object_parent_org pref
join
-- m_org_closure oc on pref.targetoid = oc.descendant_oid
m_org_clsr('4e84dcec-eff6-4f1c-9bad-929e98dea3fa') oc on pref.targetoid = oc.descendant_oid
and pref.owner_oid = u.oid
and pref.ownerOid = u.oid
-- where oc.ancestor_oid = '4e84dcec-eff6-4f1c-9bad-929e98dea3fa'
);

-- using m_org_closure_internal directly 150 ms for just OIDs (600 ms full rows)
select oid from m_user u
where u.name_norm like '%45'
where u.nameNorm like '%45'
and exists (select 1 from
m_ref_object_parent_org pref
join
m_org_closure_internal oc on pref.targetoid = oc.descendant_oid
and pref.owner_oid = u.oid
and pref.ownerOid = u.oid
where oc.ancestor_oid = '4e84dcec-eff6-4f1c-9bad-929e98dea3fa'
);

WITH RECURSIVE org_h (
ancestor_oid, -- ref.targetoid
descendant_oid --ref.owner_oid
descendant_oid --ref.ownerOid
) AS (
-- gather all organizations with parents
SELECT r.targetoid, r.owner_oid
SELECT r.targetoid, r.ownerOid
FROM m_ref_object_parent_org r
WHERE r.owner_type = 'ORG'
WHERE r.ownerType = 'ORG'
UNION
-- generate their parents
SELECT par.targetoid, chi.descendant_oid -- leaving original child there generates closure
FROM m_ref_object_parent_org as par, org_h as chi
WHERE par.owner_oid = chi.ancestor_oid
WHERE par.ownerOid = chi.ancestor_oid
),
pref as (
select pref.* from m_ref_object_parent_org pref
Expand All @@ -159,24 +159,24 @@ pref as (
)
select oid from m_user u
where
u.name_norm like '%45' and
exists (select 1 from pref where pref.owner_oid = u.oid)
u.nameNorm like '%45' and
exists (select 1 from pref where pref.ownerOid = u.oid)
;
-- select count(*) from org_h;
-- select * from org_h;
;
select oid from m_user u
where u.name_norm like '%45'
where u.nameNorm like '%45'
and exists (select 1 from
m_ref_object_parent_org pref
join
org_h oc on pref.targetoid = oc.descendant_oid
and pref.owner_oid = u.oid
and pref.ownerOid = u.oid
where oc.ancestor_oid = '4e84dcec-eff6-4f1c-9bad-929e98dea3fa'
);

select * from m_ref_object_parent_org
where owner_oid = '0f9badc4-3fc2-4977-aa0a-f08c3576383d';
where ownerOid = '0f9badc4-3fc2-4977-aa0a-f08c3576383d';

select * from m_org_closure oc
where oc.descendant_oid = '6e732607-609f-46de-9747-1675868dc227';
Expand Down Expand Up @@ -206,7 +206,7 @@ select count(*) from m_user;
-- trigger with mark: orgs/closure: 59711/291099 (after refresh ~1.9s), 2m13s, ~450 orgs/s

select * from m_org o
where not exists (select 1 from m_ref_object_parent_org po where po.owner_oid = o.oid);
where not exists (select 1 from m_ref_object_parent_org po where po.ownerOid = o.oid);

select * from m_org_closure;

Expand Down
54 changes: 27 additions & 27 deletions repo/repo-sqale/sql/pgnew-eav-vs-json.sql
Expand Up @@ -43,12 +43,12 @@ create table teav (
ALTER TABLE teav ADD CONSTRAINT teav_name_key UNIQUE (name);

create table teav_ext_string (
owner_oid UUID NOT NULL references teav(oid),
ownerOid UUID NOT NULL references teav(oid),
key VARCHAR(32) NOT NULL,
value VARCHAR(255) NOT NULL,

-- this also covers the index on owner_oid FK
CONSTRAINT teav_ext_string_pk PRIMARY KEY (owner_oid, key, value)
-- this also covers the index on ownerOid FK
CONSTRAINT teav_ext_string_pk PRIMARY KEY (ownerOid, key, value)
);

CREATE INDEX teav_ext_string_key_value_idx ON teav_ext_string (key, value);
Expand Down Expand Up @@ -81,9 +81,9 @@ BEGIN

-- EAV
INSERT INTO teav (oid, name) VALUES (id, 'user-' || LPAD(r::text, 10, '0'));
INSERT INTO teav_ext_string (owner_oid, key, value) VALUES (id, 'eid', r);
INSERT INTO teav_ext_string (ownerOid, key, value) VALUES (id, 'eid', r);
FOREACH v IN ARRAY hobbies LOOP
INSERT INTO teav_ext_string (owner_oid, key, value)
INSERT INTO teav_ext_string (ownerOid, key, value)
VALUES (id, 'hobbies', v);
END LOOP;
ELSEIF r % 10 <= 1 THEN
Expand All @@ -97,9 +97,9 @@ BEGIN
('{"eid": ' || r || ', "email": "user' || r || '@mycompany.com", "other-key-' || r || '": "other-value-' || r || '"}')::jsonb
);
INSERT INTO teav (oid, name) VALUES (id, 'user-' || LPAD(r::text, 10, '0'));
INSERT INTO teav_ext_string (owner_oid, key, value) VALUES (id, 'email', 'user' || r || '@mycompany.com');
INSERT INTO teav_ext_string (owner_oid, key, value) VALUES (id, 'eid', r);
INSERT INTO teav_ext_string (owner_oid, key, value) VALUES (id, 'other-key-' || r, 'other-value-' || r);
INSERT INTO teav_ext_string (ownerOid, key, value) VALUES (id, 'email', 'user' || r || '@mycompany.com');
INSERT INTO teav_ext_string (ownerOid, key, value) VALUES (id, 'eid', r);
INSERT INTO teav_ext_string (ownerOid, key, value) VALUES (id, 'other-key-' || r, 'other-value-' || r);
ELSE
-- these values are used by many entries
hobbies := random_pick(ARRAY['eating', 'books', 'music', 'dancing', 'walking', 'jokes', 'video', 'photo'], 0.4);
Expand All @@ -111,9 +111,9 @@ BEGIN

-- EAV
INSERT INTO teav (oid, name) VALUES (id, 'user-' || LPAD(r::text, 10, '0'));
INSERT INTO teav_ext_string (owner_oid, key, value) VALUES (id, 'eid', r);
INSERT INTO teav_ext_string (ownerOid, key, value) VALUES (id, 'eid', r);
FOREACH v IN ARRAY hobbies LOOP
INSERT INTO teav_ext_string (owner_oid, key, value)
INSERT INTO teav_ext_string (ownerOid, key, value)
VALUES (id, 'hobbies', v);
END LOOP;
END IF;
Expand Down Expand Up @@ -201,7 +201,7 @@ select * from tjson where UPPER(ext->>'email') LIKE 'USER2%' LIMIT 500;
CREATE INDEX teav_ext_string_value_trgm_idx ON teav_ext_string USING gin(value gin_trgm_ops);
CREATE INDEX teav_ext_string_value_email_trgm_idx ON teav_ext_string USING gin(value gin_trgm_ops) WHERE key='email';
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'email' and es.value ILIKE 'USER2%') LIMIT 50;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'email' and es.value ILIKE 'USER2%') LIMIT 50;
select from teav_ext_string ex where es.key = 'email' and es.value ILIKE 'USER2%' limit 500;

-- selects
Expand Down Expand Up @@ -236,30 +236,30 @@ select * from tjson where ext @> '{"eid":5000}';
-- pgbench -r -P 5 -f - -t 5 << "--EOF"
select count(*) from teav_ext_string; -- out for curiosity, not practical otherwise
select count(*) from teav;
select count(*) from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'hobbies' and es.value = 'video');
select count(*) from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'hobbies' and es.value = 'sleeping');
select count(*) from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'email' and es.value LIKE 'user2%');
select count(*) from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'email' and UPPER(es.value) LIKE 'USER2%');
select count(*) from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'hobbies' and es.value = 'video');
select count(*) from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'hobbies' and es.value = 'sleeping');
select count(*) from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'email' and es.value LIKE 'user2%');
select count(*) from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'email' and UPPER(es.value) LIKE 'USER2%');
--EOF

-- selects
-- pgbench -r -P 5 -f - -t 30 << "--EOF"
select * from teav limit 500;
select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'hobbies' and es.value = 'video') limit 500;
select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'hobbies' and es.value = 'video') order by t.oid limit 500;
select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'hobbies' and es.value = 'video') and t.oid>'fffe0000-0000-0000-0000-000000000000' order by t.oid limit 500;
select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'hobbies' and es.value = 'sleeping') limit 500;
select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'hobbies' and es.value = 'sleeping') order by t.oid limit 500;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'hobbies' and es.value = 'video') limit 500;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'hobbies' and es.value = 'video') order by t.oid limit 500;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'hobbies' and es.value = 'video') and t.oid>'fffe0000-0000-0000-0000-000000000000' order by t.oid limit 500;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'hobbies' and es.value = 'sleeping') limit 500;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'hobbies' and es.value = 'sleeping') order by t.oid limit 500;
--EOF

-- pgbench -r -P 5 -f - -t 30 << "--EOF"
select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'email' and es.value LIKE 'user2%') limit 500;
select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'email' and es.value LIKE 'user2%') order by oid limit 500;
select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'email' and es.value LIKE 'user2%') and oid>'fffe0000-0000-0000-0000-000000000000' order by oid limit 500;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'email' and es.value LIKE 'user2%') limit 500;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'email' and es.value LIKE 'user2%') order by oid limit 500;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'email' and es.value LIKE 'user2%') and oid>'fffe0000-0000-0000-0000-000000000000' order by oid limit 500;

select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'email' and UPPER(es.value) LIKE 'USER2%') limit 500;
select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'email' and UPPER(es.value) LIKE 'USER2%') order by oid limit 500;
select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'email' and UPPER(es.value) LIKE 'USER2%') and oid>'fffe0000-0000-0000-0000-000000000000' order by oid limit 500;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'email' and UPPER(es.value) LIKE 'USER2%') limit 500;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'email' and UPPER(es.value) LIKE 'USER2%') order by oid limit 500;
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'email' and UPPER(es.value) LIKE 'USER2%') and oid>'fffe0000-0000-0000-0000-000000000000' order by oid limit 500;

select * from teav t where exists (select from teav_ext_string es where es.owner_oid = t.oid and es.key = 'eid' and es.value = '5000');
select * from teav t where exists (select from teav_ext_string es where es.ownerOid = t.oid and es.key = 'eid' and es.value = '5000');
--EOF

0 comments on commit 8abcf32

Please sign in to comment.