From 53639ffe6a2f338c62baba1b22c122e8823c9bb2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 19 Aug 2026 14:49:41 +0300 Subject: [PATCH] 076 computation debug and optimization --- Application.cfc | 2 +- contragent.cfm | 20 +-- contragent_rpt.cfm | 5 +- etc/hsql_plan.txt | 309 +++++++++++++++++++++++++++++++++++++++++++++ payg.cfm | 191 +++++++++++++++++++--------- 5 files changed, 451 insertions(+), 76 deletions(-) create mode 100644 etc/hsql_plan.txt diff --git a/Application.cfc b/Application.cfc index 49b730a..64d957b 100644 --- a/Application.cfc +++ b/Application.cfc @@ -86,7 +86,7 @@ - + diff --git a/contragent.cfm b/contragent.cfm index 26450b1..486f30e 100644 --- a/contragent.cfm +++ b/contragent.cfm @@ -174,7 +174,7 @@ ,siv.version ,siv.name_version ,siv.date_accept - ,siv.__index + ,siv.__index as siv_index ,siv.date_nop ,siv.date_end ,siv.is_easy @@ -189,7 +189,7 @@ ,p.__id as p_uid ,p.name ,s.probability_pc - ,d.__index + ,d.__index as deal_index ,d.__id as deal_uid ,siv.end_customer as end_customer_uid ,z.id_klienta as end_customer_wz @@ -204,7 +204,7 @@ AND siv.is_actual --AND a.is_actual AND s.probability_pc > 0 - order by version::int + order by d.__index, siv.__index, p.__id, version::int @@ -215,7 +215,7 @@ - + @@ -229,9 +229,9 @@ - - - + + + @@ -239,9 +239,9 @@ - + - + - + diff --git a/contragent_rpt.cfm b/contragent_rpt.cfm index af9feef..b2087db 100644 --- a/contragent_rpt.cfm +++ b/contragent_rpt.cfm @@ -231,9 +231,10 @@ JOIN status s ON (d.deal_status_id = s.status_id) LEFT JOIN LATERAL unnest(d.params) AS arr(param_id) ON TRUE JOIN component p ON (p.__id = arr.param_id) - WHERE d.dt_from <= CURRENT_TIMESTAMP AND (CURRENT_TIMESTAMP < d.dt_next) + WHERE d.dt_from <= CURRENT_TIMESTAMP AND (CURRENT_TIMESTAMP < d.dt_next) +ORDER BY d.siv_uid, p.__id - +

Услуги по данным CRM (из DWH, версии строк спецификации, только актуальные на сегодня, сделки с вероятностью от 50% (начиная с тестирования)

diff --git a/etc/hsql_plan.txt b/etc/hsql_plan.txt new file mode 100644 index 0000000..a10ff42 --- /dev/null +++ b/etc/hsql_plan.txt @@ -0,0 +1,309 @@ +EXPLAIN PLAN FOR +SELECT +coalesce(coalesce(c.wz, m.wz), s.wz) as wz,s.wz as wzs,c.wz as wzc,m.wz as wzm,s.end_customer_wz as wze,coalesce(s.code, m.code) as code,s.code as s_code,s.sku_code as sku_code,m.code as m_code,s.component_quantity,s.service_quantity,s.service_discount,coalesce(s.free_tier,0) as free_tier,m.dimension1,s.type,m.unit,s.ed_izm,coalesce(s.service_quantity*(100.-s.service_discount)/100.*s.price*(100.-s.component_discount)/100., 0.) as discounted_price,s.serviceStart,s.serviceEnd,s.line_key,s.price,s.component_discount,m.raw_metric,m.metric,c.contragent,c.contragent_uid,c.responsible,c.responsible_email,c.responsible_status,s.contract,s.contract_uid,s.additional_agreement,s.additional_agreement_uid,s.deal,s.deal_uid,s.abstract_service,s.modifier,s.component,s.user_description +FROM qUnifiedMetric m +FULL JOIN qSpec s ON (m.wz=s.wz AND m.code=s.sku_code) -- сервис или компонент, но не цена с типом тарификации +LEFT JOIN qContragent c ON (trim(coalesce(s.wz,m.wz))=trim(c.wz)) -- пробелы тут стоили нескольких часов работы +WHERE 1=1 --AND (s.type=3 OR NOT m.metric IS NULL) +AND EXISTS(select * from qSpec qs where qs.wz=m.wz AND qs.type=3) +--AND s.wz='WZ01031' +--AND s.wz='WZ01762' +ORDER BY coalesce(coalesce(c.wz, m.wz), s.wz), coalesce(s.code, m.code) +PLAN +1 isDistinctSelect=[false] +2 isGrouped=[false] +3 isAggregated=[false] +4 columns=[ +5 CASEWHEN arg_left=[ +6 IS NULL arg_left=[ +7 CASEWHEN arg_left=[ +8 IS NULL arg_left=[ COLUMN: PUBLIC.QCONTRAGENT.WZ +9 ]] arg_right=[ +10 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ +11 ] arg_right=[ COLUMN: PUBLIC.QCONTRAGENT.WZ +12 ]]]] arg_right=[ +13 arg_left=[ COLUMN: PUBLIC.QSPEC.WZ +14 ] arg_right=[ +15 CASEWHEN arg_left=[ +16 IS NULL arg_left=[ COLUMN: PUBLIC.QCONTRAGENT.WZ +17 ]] arg_right=[ +18 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ +19 ] arg_right=[ COLUMN: PUBLIC.QCONTRAGENT.WZ +20 ]]] nullable +21 COLUMN: PUBLIC.QSPEC.WZ AS WZS nullable +22 COLUMN: PUBLIC.QCONTRAGENT.WZ AS WZC nullable +23 COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ AS WZM nullable +24 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_WZ AS WZE nullable +25 +26 CASEWHEN arg_left=[ +27 IS NULL arg_left=[ COLUMN: PUBLIC.QSPEC.CODE +28 ]] arg_right=[ +29 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.CODE +30 ] arg_right=[ COLUMN: PUBLIC.QSPEC.CODE +31 ] nullable +32 COLUMN: PUBLIC.QSPEC.CODE AS S_CODE nullable +33 COLUMN: PUBLIC.QSPEC.SKU_CODE AS SKU_CODE nullable +34 COLUMN: PUBLIC.QUNIFIEDMETRIC.CODE AS M_CODE nullable +35 COLUMN: PUBLIC.QSPEC.COMPONENT_QUANTITY nullable +36 COLUMN: PUBLIC.QSPEC.SERVICE_QUANTITY nullable +37 COLUMN: PUBLIC.QSPEC.SERVICE_DISCOUNT nullable +38 +39 CASEWHEN arg_left=[ +40 IS NULL arg_left=[ COLUMN: PUBLIC.QSPEC.FREE_TIER +41 ]] arg_right=[ +42 arg_left=[ +43 VALUE = 0, TYPE = INTEGER] arg_right=[ COLUMN: PUBLIC.QSPEC.FREE_TIER +44 ] nullable +45 COLUMN: PUBLIC.QUNIFIEDMETRIC.DIMENSION1 nullable +46 COLUMN: PUBLIC.QSPEC.TYPE nullable +47 COLUMN: PUBLIC.QUNIFIEDMETRIC.UNIT nullable +48 COLUMN: PUBLIC.QSPEC.ED_IZM nullable +49 +50 CASEWHEN arg_left=[ +51 IS NULL arg_left=[ +52 DIVIDE arg_left=[ +53 MULTIPLY arg_left=[ +54 MULTIPLY arg_left=[ +55 DIVIDE arg_left=[ +56 MULTIPLY arg_left=[ COLUMN: PUBLIC.QSPEC.SERVICE_QUANTITY +57 ] arg_right=[ +58 SUBTRACT arg_left=[ +59 VALUE = 100, TYPE = DECIMAL] arg_right=[ COLUMN: PUBLIC.QSPEC.SERVICE_DISCOUNT +60 ]]] arg_right=[ +61 VALUE = 100, TYPE = DECIMAL]] arg_right=[ COLUMN: PUBLIC.QSPEC.PRICE +62 ]] arg_right=[ +63 SUBTRACT arg_left=[ +64 VALUE = 100, TYPE = DECIMAL] arg_right=[ COLUMN: PUBLIC.QSPEC.COMPONENT_DISCOUNT +65 ]]] arg_right=[ +66 VALUE = 100, TYPE = DECIMAL]]] arg_right=[ +67 arg_left=[ +68 VALUE = 0, TYPE = DECIMAL] arg_right=[ +69 DIVIDE arg_left=[ +70 MULTIPLY arg_left=[ +71 MULTIPLY arg_left=[ +72 DIVIDE arg_left=[ +73 MULTIPLY arg_left=[ COLUMN: PUBLIC.QSPEC.SERVICE_QUANTITY +74 ] arg_right=[ +75 SUBTRACT arg_left=[ +76 VALUE = 100, TYPE = DECIMAL] arg_right=[ COLUMN: PUBLIC.QSPEC.SERVICE_DISCOUNT +77 ]]] arg_right=[ +78 VALUE = 100, TYPE = DECIMAL]] arg_right=[ COLUMN: PUBLIC.QSPEC.PRICE +79 ]] arg_right=[ +80 SUBTRACT arg_left=[ +81 VALUE = 100, TYPE = DECIMAL] arg_right=[ COLUMN: PUBLIC.QSPEC.COMPONENT_DISCOUNT +82 ]]] arg_right=[ +83 VALUE = 100, TYPE = DECIMAL]] nullable +84 COLUMN: PUBLIC.QSPEC.SERVICESTART nullable +85 COLUMN: PUBLIC.QSPEC.SERVICEEND nullable +86 COLUMN: PUBLIC.QSPEC.LINE_KEY nullable +87 COLUMN: PUBLIC.QSPEC.PRICE nullable +88 COLUMN: PUBLIC.QSPEC.COMPONENT_DISCOUNT nullable +89 COLUMN: PUBLIC.QUNIFIEDMETRIC.RAW_METRIC nullable +90 COLUMN: PUBLIC.QUNIFIEDMETRIC.METRIC nullable +91 COLUMN: PUBLIC.QCONTRAGENT.CONTRAGENT nullable +92 COLUMN: PUBLIC.QCONTRAGENT.CONTRAGENT_UID nullable +93 COLUMN: PUBLIC.QCONTRAGENT.RESPONSIBLE nullable +94 COLUMN: PUBLIC.QCONTRAGENT.RESPONSIBLE_EMAIL nullable +95 COLUMN: PUBLIC.QCONTRAGENT.RESPONSIBLE_STATUS nullable +96 COLUMN: PUBLIC.QSPEC.CONTRACT nullable +97 COLUMN: PUBLIC.QSPEC.CONTRACT_UID nullable +98 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT nullable +99 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT_UID nullable +100 COLUMN: PUBLIC.QSPEC.DEAL nullable +101 COLUMN: PUBLIC.QSPEC.DEAL_UID nullable +102 COLUMN: PUBLIC.QSPEC.ABSTRACT_SERVICE nullable +103 COLUMN: PUBLIC.QSPEC.MODIFIER nullable +104 COLUMN: PUBLIC.QSPEC.COMPONENT nullable +105 COLUMN: PUBLIC.QSPEC.USER_DESCRIPTION nullable +106 +107 ] +108 [range variable 1 +109 join type=INNER +110 table=QUNIFIEDMETRIC +111 alias=M +112 cardinality=3931 +113 access=FULL SCAN +114 join condition = [index=SYS_IDX_10266 +115 ] +116 ][range variable 2 +117 join type=FULL +118 table=QSPEC +119 alias=S +120 cardinality=4819 +121 access=INDEX PRED +122 join condition = [index=SYS_IDX_T_10270 +123 start conditions=[ +124 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.WZ +125 ] arg_right=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ +126 ]] +127 other condition=[ +128 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.SKU_CODE +129 ] arg_right=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.CODE +130 ]] +131 ] +132 where condition = [ +133 EXISTS arg_left=[ +134 QUERY isDistinctSelect=[false] +135 isGrouped=[false] +136 isAggregated=[false] +137 columns=[ COLUMN: PUBLIC.QSPEC.WZ nullable +138 COLUMN: PUBLIC.QSPEC.CONTRAGENT_UID nullable +139 COLUMN: PUBLIC.QSPEC.CODE nullable +140 COLUMN: PUBLIC.QSPEC.SKU_CODE nullable +141 COLUMN: PUBLIC.QSPEC.PRICE nullable +142 COLUMN: PUBLIC.QSPEC.COMPONENT_DISCOUNT nullable +143 COLUMN: PUBLIC.QSPEC.CONTRAGENT nullable +144 COLUMN: PUBLIC.QSPEC.CONTRACT nullable +145 COLUMN: PUBLIC.QSPEC.CONTRACT_UID nullable +146 COLUMN: PUBLIC.QSPEC.DEAL nullable +147 COLUMN: PUBLIC.QSPEC.DEAL_UID nullable +148 COLUMN: PUBLIC.QSPEC.ABSTRACT_SERVICE nullable +149 COLUMN: PUBLIC.QSPEC.MODIFIER nullable +150 COLUMN: PUBLIC.QSPEC.USER_DESCRIPTION nullable +151 COLUMN: PUBLIC.QSPEC.LINE_KEY nullable +152 COLUMN: PUBLIC.QSPEC.SERVICESTART nullable +153 COLUMN: PUBLIC.QSPEC.SERVICEEND nullable +154 COLUMN: PUBLIC.QSPEC.SERVICE_DISCOUNT nullable +155 COLUMN: PUBLIC.QSPEC.SERVICE_QUANTITY nullable +156 COLUMN: PUBLIC.QSPEC.ED_IZM nullable +157 COLUMN: PUBLIC.QSPEC.COMPONENT nullable +158 COLUMN: PUBLIC.QSPEC.TYPE nullable +159 COLUMN: PUBLIC.QSPEC.COMPONENT_QUANTITY nullable +160 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT nullable +161 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT_UID nullable +162 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_UID nullable +163 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_WZ nullable +164 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_NAME nullable +165 COLUMN: PUBLIC.QSPEC.FREE_TIER nullable +166 +167 ] +168 [range variable 1 +169 join type=INNER +170 table=QSPEC +171 alias=QS +172 cardinality=4819 +173 access=INDEX PRED +174 join condition = [index=SYS_IDX_T_10270 +175 start conditions=[ +176 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.WZ +177 ] arg_right=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ +178 ] +179 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.TYPE +180 ] arg_right=[ +181 VALUE = 3, TYPE = INTEGER]] +182 ] +183 ] ] +184 ] ] +185 ][range variable 3 +186 join type=LEFT OUTER +187 table=QCONTRAGENT +188 alias=C +189 cardinality=2912 +190 access=FULL SCAN +191 join condition = [index=SYS_IDX_10267 +192 other condition=[ +193 EQUAL arg_left=[ +194 FUNCTION =[ +195 TRIM([ +196 VALUE = 26, TYPE = INTEGER][ +197 VALUE = ' ', TYPE = CHARACTER][ +198 CASEWHEN arg_left=[ +199 IS NULL arg_left=[ COLUMN: PUBLIC.QSPEC.WZ +200 ]] arg_right=[ +201 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ +202 ] arg_right=[ COLUMN: PUBLIC.QSPEC.WZ +203 ]]]) returns VARCHAR] +204 ] arg_right=[ +205 FUNCTION =[ +206 TRIM([ +207 VALUE = 26, TYPE = INTEGER][ +208 VALUE = ' ', TYPE = CHARACTER][ COLUMN: PUBLIC.QCONTRAGENT.WZ +209 ]) returns VARCHAR] +210 ]] +211 ] +212 ]] +213 order by=[ +214 +215 CASEWHEN arg_left=[ +216 IS NULL arg_left=[ +217 CASEWHEN arg_left=[ +218 IS NULL arg_left=[ COLUMN: PUBLIC.QCONTRAGENT.WZ +219 ]] arg_right=[ +220 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ +221 ] arg_right=[ COLUMN: PUBLIC.QCONTRAGENT.WZ +222 ]]]] arg_right=[ +223 arg_left=[ COLUMN: PUBLIC.QSPEC.WZ +224 ] arg_right=[ +225 CASEWHEN arg_left=[ +226 IS NULL arg_left=[ COLUMN: PUBLIC.QCONTRAGENT.WZ +227 ]] arg_right=[ +228 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ +229 ] arg_right=[ COLUMN: PUBLIC.QCONTRAGENT.WZ +230 ]]]] +231 CASEWHEN arg_left=[ +232 IS NULL arg_left=[ COLUMN: PUBLIC.QSPEC.CODE +233 ]] arg_right=[ +234 arg_left=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.CODE +235 ] arg_right=[ COLUMN: PUBLIC.QSPEC.CODE +236 ]]] +237 PARAMETERS=[] +238 SUBQUERIES[ +239 [level=1 +240 isDistinctSelect=[false] +241 isGrouped=[false] +242 isAggregated=[false] +243 columns=[ COLUMN: PUBLIC.QSPEC.WZ nullable +244 COLUMN: PUBLIC.QSPEC.CONTRAGENT_UID nullable +245 COLUMN: PUBLIC.QSPEC.CODE nullable +246 COLUMN: PUBLIC.QSPEC.SKU_CODE nullable +247 COLUMN: PUBLIC.QSPEC.PRICE nullable +248 COLUMN: PUBLIC.QSPEC.COMPONENT_DISCOUNT nullable +249 COLUMN: PUBLIC.QSPEC.CONTRAGENT nullable +250 COLUMN: PUBLIC.QSPEC.CONTRACT nullable +251 COLUMN: PUBLIC.QSPEC.CONTRACT_UID nullable +252 COLUMN: PUBLIC.QSPEC.DEAL nullable +253 COLUMN: PUBLIC.QSPEC.DEAL_UID nullable +254 COLUMN: PUBLIC.QSPEC.ABSTRACT_SERVICE nullable +255 COLUMN: PUBLIC.QSPEC.MODIFIER nullable +256 COLUMN: PUBLIC.QSPEC.USER_DESCRIPTION nullable +257 COLUMN: PUBLIC.QSPEC.LINE_KEY nullable +258 COLUMN: PUBLIC.QSPEC.SERVICESTART nullable +259 COLUMN: PUBLIC.QSPEC.SERVICEEND nullable +260 COLUMN: PUBLIC.QSPEC.SERVICE_DISCOUNT nullable +261 COLUMN: PUBLIC.QSPEC.SERVICE_QUANTITY nullable +262 COLUMN: PUBLIC.QSPEC.ED_IZM nullable +263 COLUMN: PUBLIC.QSPEC.COMPONENT nullable +264 COLUMN: PUBLIC.QSPEC.TYPE nullable +265 COLUMN: PUBLIC.QSPEC.COMPONENT_QUANTITY nullable +266 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT nullable +267 COLUMN: PUBLIC.QSPEC.ADDITIONAL_AGREEMENT_UID nullable +268 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_UID nullable +269 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_WZ nullable +270 COLUMN: PUBLIC.QSPEC.END_CUSTOMER_NAME nullable +271 COLUMN: PUBLIC.QSPEC.FREE_TIER nullable +272 +273 ] +274 [range variable 1 +275 join type=INNER +276 table=QSPEC +277 alias=QS +278 cardinality=4819 +279 access=INDEX PRED +280 join condition = [index=SYS_IDX_T_10270 +281 start conditions=[ +282 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.WZ +283 ] arg_right=[ COLUMN: PUBLIC.QUNIFIEDMETRIC.WZ +284 ] +285 EQUAL arg_left=[ COLUMN: PUBLIC.QSPEC.TYPE +286 ] arg_right=[ +287 VALUE = 3, TYPE = INTEGER]] +288 ] +289 ] ] +290 ]] + +----------------------- +Here is a detailed breakdown of your HSQLDB execution plan. The query contains a hidden performance trap—specifically, an accidental implicit Inner Join conversion and a costly Full Table Scan—which we can optimize.🚨 Critical Performance Issues Found1. The FULL JOIN Was Converted into an INNER JOIN (Lines 108–109)Look closely at Line 109: join type=INNER for table QUNIFIEDMETRIC (M).Why this happened: In your WHERE clause, you have an EXISTS subquery: where qs.wz = m.wz.The impact: Because m.wz must match something in qSpec to pass the EXISTS filter, any row where M exists but S does not (the "left" part of your FULL JOIN) is immediately discarded. HSQLDB noticed this and optimized your FULL JOIN down to a standard INNER JOIN.2. Full Table Scan on QCONTRAGENT (Lines 185–191)Look at Line 190: access=FULL SCAN for table QCONTRAGENT (C).Why this happened: Your join condition uses a function: ON (trim(coalesce(s.wz, m.wz)) = trim(c.wz)).The impact: Applying trim() to a column prevents the database from using standard indexes on c.wz. For every single row combination, HSQLDB is forced to scan the entire 2,912-row table sequentially.🔍 Step-by-Step Plan BreakdownStep 1: Scan QUNIFIEDMETRIC M (Lines 108–113)Access: FULL SCANRows: 3,931The database starts here because it serves as the base for evaluating the EXISTS clause.Step 2: Probe QSPEC S via Index (Lines 116–131)Access: INDEX PRED (Index Predicate) using index SYS_IDX_T_10270.Execution: It successfully uses the index on wz to fetch corresponding records from S. The secondary condition m.code = s.sku_code is evaluated as an "other condition" (filter) afterwards.Step 3: Evaluate the EXISTS Subquery (Lines 132–184)Access: INDEX PRED on QSPEC QS.The database runs a semi-join utilizing the index to verify if a matching wz with type = 3 exists. This part is relatively efficient.Step 4: Scan and Join QCONTRAGENT C (Lines 185–202)Access: FULL SCANBecause of the trim(...) wrappers, it falls back to a nested loop full table scan to evaluate the dynamic string alignment.🛠️ Optimization RecommendationsTo speed up this query dramatically, apply these two adjustments:1. Explicitly clean the data instead of using trim() in the joinIf possible, run a one-time script to permanently clean whitespace from your database tables:sqlUPDATE qContragent SET wz = TRIM(wz); +UPDATE qSpec SET wz = TRIM(wz); +UPDATE qUnifiedMetric SET wz = TRIM(wz); +Use code with caution.Once cleaned, rewrite the join smoothly to leverage indexes:sqlLEFT JOIN qContragent c ON (coalesce(s.wz, m.wz) = c.wz) +Use code with caution.2. Downgrade FULL JOIN to LEFT JOIN or INNER JOINSince your EXISTS condition fundamentally breaks the FULL JOIN behavior anyway, changing the keyword to LEFT JOIN qSpec s or INNER JOIN qSpec s makes your code match its real execution pathway, preventing the optimizer from doing unnecessary planning logic.If you'd like to check how to implement a functional index to bypass the trim() problem, let me know which HSQLDB version you are currently running! \ No newline at end of file diff --git a/payg.cfm b/payg.cfm index 1225992..c35dcf7 100644 --- a/payg.cfm +++ b/payg.cfm @@ -14,9 +14,10 @@ + - + select distinct p.code from elma.deals d join elma.deals_services siv on (d.__id=ANY(siv.deal)) @@ -31,25 +32,28 @@ - - select k.id_klienta as wz, k.__id::text as contragent_uid, k.__name as contragent, + + select upper(trim(k.id_klienta)) as wz, k.__id::text as contragent_uid, k.__name as contragent, c.__name as responsible, c.email as responsible_email, c.__status_status as responsible_status from elma.companies k LEFT OUTER JOIN elma.comp_users_ext c on (k.responsible=c.__id) where k."__deletedAt" IS NULL + + AND k.id_klienta like + qContragent:#getTickCount()-request.startTickCount# - - - - - select k.id_klienta as wz, k.__id::text as contragent_uid, + + WITH + status(status, status_id, probability_pc) + AS (VALUES + ('Закрыта неуспешно',7,0),('Закрыта успешно',6,100),('Договор подписан',5,100),('Договор на подписании',15,90),('Договор на согласовании',12,70), + ('Тестирование',8,50),('Отправлено ТКП',10,20),('Внутреннее согласование',37,10),('Проработка решения',4,10),('Сбор потребностей',1,0) + ) + select upper(trim(k.id_klienta)) as wz, k.__id::text as contragent_uid, p.code, SUBSTRING(p.code FROM 1 FOR LENGTH(p.code) - 2) as sku_code, p.price, p.discount as component_discount, k.__name as contragent, a.__name as contract, a.__id::text as contract_uid, d.__name as deal, d.__id::text as deal_uid, siv.abstractive_service as abstract_service, siv.modifier, siv.user_description, siv.hash as line_key @@ -61,9 +65,14 @@ ,z.id_klienta as end_customer_wz ,z.__name as end_customer_name ,ft.free_tier + ,s.probability_pc + ,siv.__id::text as siv_uid from elma.deals d - join elma.deals_services siv on (d.__id=ANY(siv.deal)) - join elma.service_parametrs p on (p.__id = ANY(siv.params)) + JOIN STATUS s ON (d.__status_status = s.status_id) + join elma.deals_services siv on (d.__id=ANY(siv.deal)) + --join elma.service_parametrs p on (p.__id = ANY(siv.params)) + LEFT JOIN LATERAL unnest(siv.params) AS arr(param_id) ON TRUE + JOIN elma.service_parametrs p ON (p.__id = arr.param_id) join elma.companies k on (d._companies=k.__id) join elma.additional_agreements aa on (aa.__id = ANY(siv.additional_agreement)) join elma.aggrements a on (aa.contract_uid = a.__id) @@ -72,10 +81,22 @@ where p.type IN (2,3) AND aa.is_actual AND siv.date_nop < AND (siv.date_end > OR siv.date_end IS NULL)/*****/ + AND aa."__deletedAt" IS NULL + AND a."__deletedAt" IS NULL + AND d."__deletedAt" IS NULL + AND siv."__deletedAt" IS NULL + AND p."__deletedAt" IS NULL + AND p.cnt <> 0 --похоже, только так можно отфильтровать паразитные строки с нулем + + AND k.id_klienta like + --AND k.id_klienta='WZ01031' --AND k.id_klienta='WZ01112' order by k.id_klienta, p.code + qSpec:#getTickCount()-request.startTickCount# @@ -91,7 +112,7 @@ - select m.clientid as wz, vdc.name as vdc, + select upper(trim(m.clientid)) as wz, vdc.name as vdc, case WHEN vdc.name LIKE '%-v1cl1%' THEN 'iaas.ngc.i29' WHEN vdc.name LIKE '%-v1cl2%' THEN 'iaas.ngc.i31' @@ -105,15 +126,20 @@ from ngcloud_ru.capacity_resource join ngcloud_ru.vdc on capacity_resource.vdc_id=vdc.id join ngcloud_ru.tenant t on (t.id=vdc.tenant_id) - left outer join - (select tenant_id, ts, metadata_id, - ROW_NUMBER() OVER (PARTITION BY tenant_id ORDER BY ts desc, metadata_id desc) as rn - from ngcloud_ru.tenant_metadata - ) tm on (t.id = tm.tenant_id AND tm.rn = 1) - left outer join ngcloud_ru.metadata m on (tm.metadata_id=m.id) + LEFT JOIN LATERAL ( + SELECT m.clientid + FROM ngcloud_ru.tenant_metadata tm + JOIN ngcloud_ru.metadata m ON tm.metadata_id = m.id + WHERE tm.tenant_id = t.id + ORDER BY tm.ts DESC, tm.metadata_id DESC + LIMIT 1 + ) m ON true where length(m.clientid) > 0 AND capacity_resource.timestamp >= - AND capacity_resource.timestamp < + AND capacity_resource.timestamp < + + AND m.clientid like + group by m.clientid, vdc.name order by m.clientid, vdc.name; @@ -133,8 +159,8 @@ - - select m.clientid as wz, vdc.name as vdc, + + select upper(trim(m.clientid)) as wz, vdc.name as vdc, case WHEN vdc.name LIKE '%-v1cl1%' THEN 'iaas.ngc.i29' WHEN vdc.name LIKE '%-v1cl2%' THEN 'iaas.ngc.i31' @@ -156,16 +182,21 @@ from ngcloud_ru.capacity_storage join ngcloud_ru.vdc on capacity_storage.vdc_id=vdc.id join ngcloud_ru.tenant t on t.id=vdc.tenant_id - left outer join - (select tenant_id, ts, metadata_id, - ROW_NUMBER() OVER (PARTITION BY tenant_id ORDER BY ts desc, metadata_id desc) as rn - from ngcloud_ru.tenant_metadata - ) tm on (t.id = tm.tenant_id AND tm.rn = 1) - left outer join ngcloud_ru.metadata m on (tm.metadata_id=m.id) + LEFT JOIN LATERAL ( + SELECT m.clientid + FROM ngcloud_ru.tenant_metadata tm + JOIN ngcloud_ru.metadata m ON tm.metadata_id = m.id + WHERE tm.tenant_id = t.id + ORDER BY tm.ts DESC, tm.metadata_id DESC + LIMIT 1 + ) m ON true join ngcloud_ru.storage_profile_types on capacity_storage.storage_profile_types_id=storage_profile_types.id where length(m.clientid) > 0 AND capacity_storage.timestamp >= AND capacity_storage.timestamp < + + AND m.clientid like + group by m.clientid, vdc.name, storage_profile_types.name order by m.clientid, vdc.name, storage_profile_types.name; @@ -178,7 +209,7 @@ - + select max(capacity_storage.timestamp) as dt_load from ngcloud_ru.capacity_storage qStorageAge:#getTickCount()-request.startTickCount# @@ -188,7 +219,7 @@ HOT_FREE_LIMIT 1 10 1 100 ---> - + select /* *** ниже дублирование кода агрегации - round ceil etc, обратить внимание при правке */ (sum(bucket_stat.usage_rgw_main_size_actual)/) as vol_B ,sum(bucket_stat.usage_rgw_main_size_actual)//1024/1024/1024 as vol_GB @@ -204,7 +235,10 @@ HOT_FREE_LIMIT 1 10 1 100 join s3billing.bucket_info ON bucket_info.id=bucket_stat.bucket_id where bucket_stat.placement_id in (1,2) AND bucket_stat.timestamp_addition >= - AND bucket_stat.timestamp_addition < + AND bucket_stat.timestamp_addition < + + AND 'WZ'||lpad(bucket_stat.owner, 5, '0') like /*выглядит очень неэффективным запросом*/ + group by bucket_stat.owner, bucket_stat.placement_id, bucket_info.name order by bucket_stat.owner, bucket_stat.placement_id, bucket_info.name; @@ -216,13 +250,13 @@ HOT_FREE_LIMIT 1 10 1 100 - + select max(timestamp_addition) as dt_load from s3billing.bucket_stat qS3VolAge:#getTickCount()-request.startTickCount# - + select sum( CASE WHEN @@ -294,6 +328,9 @@ select where 1=1 AND usage_bucket_by_user.time >= AND usage_bucket_by_user.time < + + AND 'WZ'||lpad(user_info.name, 5, '0') like /*выглядит очень неэффективным запросом*/ + group by user_info.name, bucket_info.placement_id, bucket_info.name order by user_info.name, bucket_info.placement_id, bucket_info.name; @@ -305,7 +342,7 @@ select - + select max(time) as dt_load from s3billing.usage_bucket_by_user @@ -353,26 +390,40 @@ order by wz, code - + + + +/*EXPLAIN PLAN FOR*/ SELECT coalesce(coalesce(c.wz, m.wz), s.wz) as wz - - s.wz as wzs - c.wz as wzc - - m.wz as wzm - s.end_customer_wz as wze - coalesce(s.code, m.code) as code - s.code as s_code - s.sku_code as sku_code - m.code as m_code + s.wz as wzs + c.wz as wzc + m.wz as wzm + s.end_customer_wz as wze + coalesce(s.sku_code, m.code) as code + s.code as s_code + s.sku_code as sku_code + m.code as m_code s.component_quantity s.service_quantity s.service_discount @@ -407,22 +458,30 @@ SELECT s.user_description FROM qUnifiedMetric m -FULL JOIN qSpec s ON (m.wz=s.wz AND m.code=s.sku_code) -- сервис или компонент, но не цена с типом тарификации -LEFT JOIN qContragent c ON (trim(coalesce(s.wz,m.wz))=trim(c.wz)) -- пробелы тут стоили нескольких часов работы - -WHERE 1=1 --AND (s.type=3 OR NOT m.metric IS NULL) +FULL JOIN qSpec s ON (m.wz=s.wz AND m.code=s.sku_code) -- сервис или компонент, но не цена с типом тарификации, суффикс типа тарификации отрезан +LEFT JOIN qContragent c ON ((coalesce(s.wz,m.wz))=(c.wz)) -- пробелы в составе WZ стоили нескольких часов работы +--(поскольку trim слева в джойне катастрофически замедляет работу, делаем чистку выше при формировании исходных резалтсетов) +WHERE 1=1 AND EXISTS(select * from qSpec qs where qs.wz=m.wz AND qs.type=3) + + AND ( + m.wz like + OR s.wz like + OR c.wz like + ) + + --AND s.wz='WZ01031' ---AND s.wz='WZ01762' +--AND s.wz='WZ01762 ORDER BY coalesce(coalesce(c.wz, m.wz), s.wz), coalesce(s.code, m.code) - + qCharge:#getTickCount()-request.startTickCount# @@ -460,6 +519,7 @@ ORDER BY coalesce(coalesce(c.wz, m.wz), s.wz), coalesce(s.code, m.code) Период с по Только PAYG checked/> +WZ по вхождению подстроки, с учетом регистра @@ -482,7 +542,7 @@ S3 операции и трафик: #dateFormat(qS3OpsTrfAge.dt_load,'YYYY-M
- + @@ -492,15 +552,15 @@ S3 операции и трафик: #dateFormat(qS3OpsTrfAge.dt_load,'YYYY-M - - + + - - + + @@ -540,17 +600,22 @@ S3 операции и трафик: #dateFormat(qS3OpsTrfAge.dt_load,'YYYY-M + + + + + class="gray"> - style="background:lightgreen;color:black;">#s_code# + @@ -592,16 +657,16 @@ S3 операции и трафик: #dateFormat(qS3OpsTrfAge.dt_load,'YYYY-M - + - + - + @@ -611,8 +676,8 @@ S3 операции и трафик: #dateFormat(qS3OpsTrfAge.dt_load,'YYYY-M - - + +
__indexdeal index user description Компонентыversion name version date accept__indexdate nopdate endline version indexНОУКОУ is easy Вер.% Дополнительное соглашение
#__index##deal_index# #user_description# @@ -278,7 +278,7 @@ #version# #name_version# #date_accept##__index##siv_index# #dateFormat(date_nop,'YYYY-MM-DD')# #dateFormat(date_end,'YYYY-MM-DD')# #is_easy# Артикул специф. Кол-во специф. Артикул метр.ДетализацияДетализация Кол-во метр. Free Tier. Опл. объем   УслугаКомпонентУслугаКомпонент Клиентс. назв. GPL с НДС Скидка%Дата НОУ ***Дата оконч.Дата НОУДата КОУ Ключ строки Сырая метрика
#currentRow# style="background:lightgreen;color:black;">#s_code# "err r""r">#component_quantity# #m_code# #dimension1#
#code#Итого #code#: #round(final_metric_dimension_1,3)# #free_tier# #max(ceiling(final_metric_dimension_1) - free_tier, 0)# #unit# [#ed_izm#]#gaussianRoundSafe(discounted_price,2)##current_price# #gaussianRoundSafe(cost_dimension_1,2)#
Итого #wz# #contragent#:#accum_cost_svc#Итого #wz# #contragent#:#accum_cost_svc#