@@ -1625,33 +1625,39 @@ private function parseAggregatedResults(string $result, string $type = 'event'):
16251625 /**
16261626 * Count metrics using Query objects.
16271627 *
1628+ * When $max is non-null the count is bounded at the database level via
1629+ * a `LIMIT {max}` inside a subquery — ClickHouse stops scanning once
1630+ * that many rows have been matched, keeping large counts cheap.
1631+ *
16281632 * @param array<Query> $queries
16291633 * @param string|null $type 'event', 'gauge', or null (both)
1634+ * @param int|null $max Optional upper bound (inclusive) for the count
16301635 * @return int
16311636 * @throws Exception
16321637 */
1633- public function count (array $ queries = [], ?string $ type = null ): int
1638+ public function count (array $ queries = [], ?string $ type = null , ? int $ max = null ): int
16341639 {
16351640 $ this ->setOperationContext ('count() ' );
16361641
16371642 if ($ type !== null ) {
1638- return $ this ->countFromTable ($ queries , $ type );
1643+ return $ this ->countFromTable ($ queries , $ type, $ max );
16391644 }
16401645
16411646 // Count from both tables
1642- return $ this ->countFromTable ($ queries , Usage::TYPE_EVENT )
1643- + $ this ->countFromTable ($ queries , Usage::TYPE_GAUGE );
1647+ return $ this ->countFromTable ($ queries , Usage::TYPE_EVENT , $ max )
1648+ + $ this ->countFromTable ($ queries , Usage::TYPE_GAUGE , $ max );
16441649 }
16451650
16461651 /**
16471652 * Count metrics from a specific table.
16481653 *
16491654 * @param array<Query> $queries
16501655 * @param string $type
1656+ * @param int|null $max Optional upper bound (inclusive) for the count
16511657 * @return int
16521658 * @throws Exception
16531659 */
1654- private function countFromTable (array $ queries , string $ type ): int
1660+ private function countFromTable (array $ queries , string $ type, ? int $ max = null ): int
16551661 {
16561662 $ tableName = $ this ->getTableForType ($ type );
16571663 $ fromTable = $ this ->buildTableReference ($ tableName );
@@ -1665,10 +1671,20 @@ private function countFromTable(array $queries, string $type): int
16651671 $ whereClause = $ whereData ['clause ' ];
16661672 $ params = $ whereData ['params ' ];
16671673
1668- $ sql = "
1669- SELECT COUNT(*) as total FROM {$ fromTable }{$ whereClause }
1670- FORMAT JSON
1671- " ;
1674+ if ($ max !== null ) {
1675+ $ params ['max ' ] = $ max ;
1676+ $ sql = "
1677+ SELECT COUNT(*) as total FROM (
1678+ SELECT 1 FROM {$ fromTable }{$ whereClause } LIMIT {max:UInt64}
1679+ ) sub
1680+ FORMAT JSON
1681+ " ;
1682+ } else {
1683+ $ sql = "
1684+ SELECT COUNT(*) as total FROM {$ fromTable }{$ whereClause }
1685+ FORMAT JSON
1686+ " ;
1687+ }
16721688
16731689 $ result = $ this ->query ($ sql , $ params );
16741690 $ json = json_decode ($ result , true );
0 commit comments