perf(selfop): cover range reads and stream yearly SKU aggregation
This commit is contained in:
+9
-4
@@ -28,7 +28,8 @@ public final class AnalyticsReadSql {
|
||||
}
|
||||
return sql;
|
||||
}
|
||||
private static String cte(String kind){
|
||||
private static String cte(AnalyticsSqlRequest request){
|
||||
String kind=request.kind();
|
||||
if("HOT".equals(kind))return hotSalesCte();
|
||||
if("SLOW".equals(kind))return rankingCte();
|
||||
String localEvidence="CONVERT_TZ(evidence_at_utc,'+00:00','+08:00')";
|
||||
@@ -91,7 +92,11 @@ public final class AnalyticsReadSql {
|
||||
// Aggregate facts before joining SKU evidence. Repeating boundary expressions
|
||||
// inside every fact's SUM dominated the long-window MySQL execution profile.
|
||||
int rangeStart=sql.indexOf(" ranged AS (");int rangeEnd=sql.indexOf(" metric_sales AS (",rangeStart);
|
||||
sql=sql.substring(0,rangeStart)+" ranged AS (SELECT d.customer_code,d.sku_code,SUM(d.outbound_quantity) observed_sum,"
|
||||
// Only the measured maximum chart window uses SKU-ordered coverage; short windows retain date-range access.
|
||||
String rangedHint=request.from()!=null&&request.until()!=null
|
||||
&&java.time.temporal.ChronoUnit.DAYS.between(request.from(),request.until())==366
|
||||
?"/*+ INDEX(d idx_selfop_daily_sku_cover) */ ":"";
|
||||
sql=sql.substring(0,rangeStart)+" ranged AS (SELECT "+rangedHint+"d.customer_code,d.sku_code,SUM(d.outbound_quantity) observed_sum,"
|
||||
+"COUNT(*) actual_days,SUM(d.outbound_order_count) order_sum,MIN(d.quantity_unit) min_unit,MAX(d.quantity_unit) max_unit,"
|
||||
+"SUM(CASE WHEN d.business_date>=#{p.completeFrom} AND d.business_date<#{p.completeUntil} AND d.business_date<#{p.anchor} THEN 1 ELSE 0 END) actual_complete "
|
||||
+"FROM ll_selfop_sku_daily_sales d WHERE d.sales_run_id=#{p.salesRun} AND"+KEY_FILTER
|
||||
@@ -168,7 +173,7 @@ public final class AnalyticsReadSql {
|
||||
public static String page(java.util.Map<String,Object> parameters){
|
||||
var p=(AnalyticsSqlRequest)parameters.get("p");
|
||||
if("HOT".equals(p.kind()))return typed(hotPage(),p);
|
||||
return typed(cte(p.kind())+"SELECT customer_code,sku_code,product_name,quantity_unit,evidence_at_utc,unit_valid,observed_quantity,sku_order_count,"
|
||||
return typed(cte(p)+"SELECT customer_code,sku_code,product_name,quantity_unit,evidence_at_utc,unit_valid,observed_quantity,sku_order_count,"
|
||||
+"complete_day_count,partial_day_count,unknown_day_count,window_quantity,window_sku_order_count,sales30_quantity,today_quantity,"
|
||||
+"physical_quantity,available_quantity,frozen_quantity,transit_quantity,inventory_observed_at_utc,inventory_quality,inventory_reason "
|
||||
+"FROM result"+filter(p.kind()).stripTrailing()+" ORDER BY "+order(p.kind())+" LIMIT #{p.size} OFFSET #{p.offset}",p);
|
||||
@@ -236,7 +241,7 @@ public final class AnalyticsReadSql {
|
||||
"CASE WHEN inventory_quality<>'VALID' THEN CONCAT('INVENTORY_',inventory_quality) WHEN available_quantity<=0 THEN 'NO_AVAILABLE_INVENTORY' "
|
||||
+"WHEN window_quantity IS NULL THEN 'SALES_WINDOW_UNAVAILABLE' ELSE 'OBSERVATION_INSUFFICIENT' END";
|
||||
String eligible=filter(p.kind()).replace(" WHERE ","").strip();
|
||||
return typed(cte(p.kind())+", classified AS (SELECT CASE WHEN "+eligible+" THEN 1 ELSE 0 END eligible,"
|
||||
return typed(cte(p)+", classified AS (SELECT CASE WHEN "+eligible+" THEN 1 ELSE 0 END eligible,"
|
||||
+reason+" reason FROM result), counts AS (SELECT eligible,CASE WHEN eligible=1 THEN NULL ELSE reason END reason,COUNT(*) amount "
|
||||
+"FROM classified GROUP BY eligible,CASE WHEN eligible=1 THEN NULL ELSE reason END) "
|
||||
+"SELECT LEAST(SUM(CASE WHEN eligible=1 THEN amount ELSE 0 END) OVER (),100) total,reason,"
|
||||
|
||||
Reference in New Issue
Block a user