hussein-awala commented on PR #75216:
URL: https://github.com/apache/airflow/pull/75216#issuecomment-6520553233

   I ran local before/after benchmarks on PostgreSQL 14.24 and MySQL 8.0.46, 
comparing `5761c2ac` with `a315979`.
   
   The benchmark used the full Airflow schema with **1 million task rows and 
100 benchmark pools**, preserving indexes and foreign keys. Each case had three 
warmups and **20 measured samples per implementation**, with processes ordered 
before/after/after/before. All responses matched.
   
   Median API request latency:
   
   | Database | Workload | Request | Before | This PR |
   |---|---|---|---:|---:|
   | PostgreSQL | 10,000 active tasks | 50 pools | 202.4 ms | 10.4 ms |
   | PostgreSQL | 188,200 active tasks | 50 pools | 239.7 ms | 24.3 ms |
   | MySQL | 10,000 active tasks | 50 pools | 177.1 ms | 63.9 ms |
   | MySQL | 188,200 active tasks | 50 pools | 591.1 ms | 494.3 ms |
   | PostgreSQL | 901,000 active tasks | 10 filtered pools | **43.6 ms** | 
**56.3 ms** |
   
   For a 50-pool response, SQL statement counts dropped from **304 to 6**.
   
   The shared scheduler aggregation, `Pool.slots_stats(lock_rows=True)`, also 
showed workload-dependent results:
   
   | Database | Active tasks | Before | This PR |
   |---|---:|---:|---:|
   | PostgreSQL | 10,000 | 3.21 ms | 3.65 ms |
   | PostgreSQL | 188,200 | 17.88 ms | 20.45 ms |
   | MySQL | 10,000 | 21.70 ms | 24.92 ms |
   | MySQL | 188,200 | 5,420.75 ms | 1,065.26 ms |
   
   These are local, sequential TestClient measurements, including 
authentication and serialization—not production throughput estimates. Airflow 
ran in an AMD64 container on an ARM64 VM.
   
   The PostgreSQL filtered-page regression is the remaining concern. In that 
case, the requested ten pools contained only **1,000 active tasks**, while 
**900,000 active tasks belonged to unrelated pools**. PostgreSQL chose a 
parallel scan of the entire task table before joining the selected pools.
   
   Could we retain `TaskInstance.pool.in_(pool_names)` alongside the 
`Pool.pool` filter?
   
   ```python
   if pool_names is not None:
       state_count_query = state_count_query.filter(
           Pool.pool.in_(pool_names),
           TaskInstance.pool.in_(pool_names),
       )
   ```
   
   Adding this predicate preserved the aggregate results and used `ti_pool` to 
read only the 1,000 matching task rows. A separate aggregate-only diagnostic 
dropped from **51.8 ms to 0.97 ms**. This retains the canonical-name 
join/grouping that fixes MySQL collation handling while restoring efficient 
PostgreSQL filtering.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to