Skip to content

Commit f7a6d0d

Browse files
authored
Merge pull request #1582 from BoostryJP/feature/#1580
Optimize row count query performance
2 parents 414c48e + 8dd489c commit f7a6d0d

10 files changed

+92
-59
lines changed

app/api/routers/bc_explorer.py

+20-14
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ async def list_block_data(
125125
stmt = stmt.where(IDXBlockData.number <= to_block_number)
126126

127127
count = await async_session.scalar(
128-
select(func.count()).select_from(stmt.subquery())
128+
stmt.with_only_columns(func.count()).select_from(IDXBlockData).order_by(None)
129129
)
130130

131131
# Sort
@@ -134,18 +134,22 @@ async def list_block_data(
134134
else:
135135
stmt = stmt.order_by(desc(IDXBlockData.number))
136136

137+
if (
138+
await async_session.scalar(
139+
stmt.with_only_columns(func.count())
140+
.select_from(IDXBlockData)
141+
.order_by(None)
142+
)
143+
> BLOCK_RESPONSE_LIMIT
144+
):
145+
raise ResponseLimitExceededError("Search results exceed the limit")
146+
137147
# Pagination
138148
if limit is not None:
139149
stmt = stmt.limit(limit)
140150
if offset is not None:
141151
stmt = stmt.offset(offset)
142152

143-
if (
144-
await async_session.scalar(select(func.count()).select_from(stmt.subquery()))
145-
> BLOCK_RESPONSE_LIMIT
146-
):
147-
raise ResponseLimitExceededError("Search results exceed the limit")
148-
149153
block_data_tmp: Sequence[IDXBlockData] = (await async_session.scalars(stmt)).all()
150154

151155
block_data = [
@@ -269,24 +273,26 @@ async def list_tx_data(
269273
stmt = stmt.where(IDXTxData.to_address == to_checksum_address(to_address))
270274

271275
count = await async_session.scalar(
272-
select(func.count()).select_from(stmt.subquery())
276+
stmt.with_only_columns(func.count()).select_from(IDXTxData).order_by(None)
273277
)
274278

275279
# Sort
276280
stmt = stmt.order_by(desc(IDXTxData.created))
277281

282+
if (
283+
await async_session.scalar(
284+
stmt.with_only_columns(func.count()).select_from(IDXTxData).order_by(None)
285+
)
286+
> TX_RESPONSE_LIMIT
287+
):
288+
raise ResponseLimitExceededError("Search results exceed the limit")
289+
278290
# Pagination
279291
if limit is not None:
280292
stmt = stmt.limit(limit)
281293
if offset is not None:
282294
stmt = stmt.offset(offset)
283295

284-
if (
285-
await async_session.scalar(select(func.count()).select_from(stmt.subquery()))
286-
> TX_RESPONSE_LIMIT
287-
):
288-
raise ResponseLimitExceededError("Search results exceed the limit")
289-
290296
tx_data_tmp: Sequence[IDXTxData] = (await async_session.scalars(stmt)).all()
291297

292298
tx_data = [

app/api/routers/notification.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ async def list_all_notifications(
7171

7272
stmt = select(Notification)
7373
total = await async_session.scalar(
74-
select(func.count()).select_from(stmt.subquery())
74+
stmt.with_only_columns(func.count()).select_from(Notification).order_by(None)
7575
)
7676

7777
# Search Filter
@@ -82,7 +82,7 @@ async def list_all_notifications(
8282
if priority is not None:
8383
stmt = stmt.where(Notification.priority == priority)
8484
count = await async_session.scalar(
85-
select(func.count()).select_from(stmt.subquery())
85+
stmt.with_only_columns(func.count()).select_from(Notification).order_by(None)
8686
)
8787

8888
# Sort

app/api/routers/position.py

+14-6
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,10 @@ async def get_list_from_index(
190190
)
191191
.order_by(Listing.id)
192192
)
193-
194193
total = await async_session.scalar(
195-
select(func.count()).select_from(stmt.subquery())
194+
select(func.count()).select_from(
195+
stmt.with_only_columns(1).order_by(None).subquery()
196+
)
196197
)
197198
count = total
198199
if limit is not None:
@@ -786,9 +787,10 @@ async def get_list_from_index(
786787
)
787788
.order_by(Listing.id)
788789
)
789-
790790
total = await async_session.scalar(
791-
select(func.count()).select_from(stmt.subquery())
791+
select(func.count()).select_from(
792+
stmt.with_only_columns(1).order_by(None).subquery()
793+
)
792794
)
793795
count = total
794796
if limit is not None:
@@ -906,8 +908,11 @@ async def get_list_from_index(
906908
)
907909

908910
total = await async_session.scalar(
909-
select(func.count()).select_from(stmt.subquery())
911+
select(func.count()).select_from(
912+
stmt.with_only_columns(1).order_by(None).subquery()
913+
)
910914
)
915+
911916
count = total
912917
if limit is not None:
913918
stmt = stmt.limit(limit)
@@ -1479,8 +1484,11 @@ async def list_all_token_position(
14791484
)
14801485

14811486
total = await async_session.scalar(
1482-
select(func.count()).select_from(stmt.subquery())
1487+
select(func.count()).select_from(
1488+
stmt.with_only_columns(1).order_by(None).subquery()
1489+
)
14831490
)
1491+
14841492
count = total
14851493

14861494
if limit is not None:

app/api/routers/position_lock.py

+13-5
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,18 @@ async def __call__(
119119
)
120120

121121
total = await async_session.scalar(
122-
select(func.count()).select_from(stmt.subquery())
122+
stmt.with_only_columns(func.count())
123+
.select_from(IDXLockedPosition)
124+
.order_by(None)
123125
)
124126

125127
if lock_address is not None:
126128
stmt = stmt.where(IDXLockedPosition.lock_address == lock_address)
127129

128130
count = await async_session.scalar(
129-
select(func.count()).select_from(stmt.subquery())
131+
stmt.with_only_columns(func.count())
132+
.select_from(IDXLockedPosition)
133+
.order_by(None)
130134
)
131135

132136
sort_attr = getattr(IDXLockedPosition, sort_item, None)
@@ -243,9 +247,13 @@ async def __call__(
243247
)
244248

245249
total = await async_session.scalar(
246-
select(func.count()).select_from(stmt_lock.subquery())
250+
stmt_lock.with_only_columns(func.count())
251+
.select_from(IDXLock)
252+
.order_by(None)
247253
) + await async_session.scalar(
248-
select(func.count()).select_from(stmt_unlock.subquery())
254+
stmt_unlock.with_only_columns(func.count())
255+
.select_from(IDXUnlock)
256+
.order_by(None)
249257
)
250258

251259
match category:
@@ -279,7 +287,7 @@ async def __call__(
279287
cast(column("data"), String).like("%" + request_query.data + "%")
280288
)
281289
count = await async_session.scalar(
282-
select(func.count()).select_from(stmt.subquery())
290+
stmt.with_only_columns(func.count()).order_by(None)
283291
)
284292

285293
# Sort

app/api/routers/token.py

+24-13
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,9 @@ async def get_token_holders(
206206
)
207207
)
208208
total = await async_session.scalar(
209-
select(func.count()).select_from(stmt.subquery())
209+
select(func.count()).select_from(
210+
stmt.with_only_columns(1).order_by(None).subquery()
211+
)
210212
)
211213

212214
if request_query.exclude_owner is True:
@@ -280,7 +282,9 @@ async def get_token_holders(
280282
stmt = stmt.where(IDXLockedPosition.value <= request_query.locked)
281283

282284
count = await async_session.scalar(
283-
select(func.count()).select_from(stmt.subquery())
285+
select(func.count()).select_from(
286+
stmt.with_only_columns(1).order_by(None).subquery()
287+
)
284288
)
285289

286290
# Pagination
@@ -386,7 +390,9 @@ async def search_token_holders(
386390
)
387391
)
388392
total = await async_session.scalar(
389-
select(func.count()).select_from(stmt.subquery())
393+
select(func.count()).select_from(
394+
stmt.with_only_columns(1).order_by(None).subquery()
395+
)
390396
)
391397

392398
if data.exclude_owner is True:
@@ -442,7 +448,9 @@ async def search_token_holders(
442448
stmt = stmt.where(IDXLockedPosition.value <= data.locked)
443449

444450
count = await async_session.scalar(
445-
select(func.count()).select_from(stmt.subquery())
451+
select(func.count()).select_from(
452+
stmt.with_only_columns(1).order_by(None).subquery()
453+
)
446454
)
447455

448456
# Sort
@@ -590,7 +598,9 @@ async def get_token_holders_count(
590598
stmt = stmt.where(IDXPosition.account_address != listed_token.owner_address)
591599

592600
_count = await async_session.scalar(
593-
select(func.count()).select_from(stmt.subquery())
601+
select(func.count()).select_from(
602+
stmt.with_only_columns(1).order_by(None).subquery()
603+
)
594604
)
595605

596606
resp_body = {"count": _count}
@@ -796,8 +806,9 @@ async def list_all_transfer_histories(
796806
to_address_tag.account_tag == request_query.account_tag,
797807
)
798808
)
809+
799810
total = await async_session.scalar(
800-
select(func.count()).select_from(stmt.subquery())
811+
stmt.with_only_columns(func.count()).order_by(None)
801812
)
802813

803814
if request_query.source_event is not None:
@@ -834,7 +845,7 @@ async def list_all_transfer_histories(
834845
stmt = stmt.where(IDXTransfer.value <= request_query.value)
835846

836847
count = await async_session.scalar(
837-
select(func.count()).select_from(stmt.subquery())
848+
stmt.with_only_columns(func.count()).order_by(None)
838849
)
839850

840851
# Pagination
@@ -892,7 +903,7 @@ async def search_transfer_histories(
892903
)
893904
)
894905
total = await async_session.scalar(
895-
select(func.count()).select_from(stmt.subquery())
906+
stmt.with_only_columns(func.count()).order_by(None)
896907
)
897908

898909
if data.source_event is not None:
@@ -925,7 +936,7 @@ async def search_transfer_histories(
925936
stmt = stmt.where(IDXTransfer.value <= data.value)
926937

927938
count = await async_session.scalar(
928-
select(func.count()).select_from(stmt.subquery())
939+
stmt.with_only_columns(func.count()).order_by(None)
929940
)
930941

931942
def _order(_order):
@@ -1042,7 +1053,7 @@ async def list_all_transfer_approval_histories(
10421053
)
10431054
)
10441055
total = await async_session.scalar(
1045-
select(func.count()).select_from(stmt.subquery())
1056+
stmt.with_only_columns(func.count()).order_by(None)
10461057
)
10471058

10481059
if request_query.from_address is not None:
@@ -1065,7 +1076,7 @@ async def list_all_transfer_approval_histories(
10651076
stmt = stmt.where(IDXTransferApproval.value <= request_query.value)
10661077

10671078
count = await async_session.scalar(
1068-
select(func.count()).select_from(stmt.subquery())
1079+
stmt.with_only_columns(func.count()).order_by(None)
10691080
)
10701081

10711082
# Pagination
@@ -1134,7 +1145,7 @@ async def search_transfer_approval_histories(
11341145
)
11351146
)
11361147
total = await async_session.scalar(
1137-
select(func.count()).select_from(stmt.subquery())
1148+
stmt.with_only_columns(func.count()).order_by(None)
11381149
)
11391150

11401151
if data.application_datetime_from is not None:
@@ -1195,7 +1206,7 @@ async def search_transfer_approval_histories(
11951206
stmt = stmt.where(IDXTransferApproval.value <= data.value)
11961207

11971208
count = await async_session.scalar(
1198-
select(func.count()).select_from(stmt.subquery())
1209+
stmt.with_only_columns(func.count()).order_by(None)
11991210
)
12001211

12011212
def _order(_order):

app/api/routers/token_bond.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ async def list_all_straight_bond_tokens(
8787
if len(request_query.address_list):
8888
stmt = stmt.where(IDXBondToken.token_address.in_(request_query.address_list))
8989
total = await async_session.scalar(
90-
select(func.count()).select_from(stmt.subquery())
90+
stmt.with_only_columns(func.count()).order_by(None)
9191
)
9292

9393
# Search Filter
@@ -128,7 +128,7 @@ async def list_all_straight_bond_tokens(
128128
if request_query.is_redeemed is not None:
129129
stmt = stmt.where(IDXBondToken.is_redeemed == request_query.is_redeemed)
130130
count = await async_session.scalar(
131-
select(func.count()).select_from(stmt.subquery())
131+
stmt.with_only_columns(func.count()).order_by(None)
132132
)
133133

134134
if sort_item == "created":
@@ -197,7 +197,7 @@ async def list_all_straight_bond_token_addresses(
197197
.where(Listing.is_public == True)
198198
)
199199
total = await async_session.scalar(
200-
select(func.count()).select_from(stmt.subquery())
200+
stmt.with_only_columns(func.count()).order_by(None)
201201
)
202202

203203
# Search Filter
@@ -238,7 +238,7 @@ async def list_all_straight_bond_token_addresses(
238238
if request_query.is_redeemed is not None:
239239
stmt = stmt.where(IDXBondToken.is_redeemed == request_query.is_redeemed)
240240
count = await async_session.scalar(
241-
select(func.count()).select_from(stmt.subquery())
241+
stmt.with_only_columns(func.count()).order_by(None)
242242
)
243243

244244
if sort_item == "created":

app/api/routers/token_coupon.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ async def list_all_coupon_tokens(
9696
if len(request_query.address_list):
9797
stmt = stmt.where(IDXCouponToken.token_address.in_(request_query.address_list))
9898
total = await async_session.scalar(
99-
select(func.count()).select_from(stmt.subquery())
99+
stmt.with_only_columns(func.count()).order_by(None)
100100
)
101101

102102
# Search Filter
@@ -119,7 +119,7 @@ async def list_all_coupon_tokens(
119119
IDXCouponToken.initial_offering_status == initial_offering_status
120120
)
121121
count = await async_session.scalar(
122-
select(func.count()).select_from(stmt.subquery())
122+
stmt.with_only_columns(func.count()).order_by(None)
123123
)
124124

125125
if sort_item == "created":
@@ -197,7 +197,7 @@ async def list_all_coupon_token_addresses(
197197
.where(Listing.is_public == True)
198198
)
199199
total = await async_session.scalar(
200-
select(func.count()).select_from(stmt.subquery())
200+
stmt.with_only_columns(func.count()).order_by(None)
201201
)
202202

203203
# Search Filter
@@ -220,7 +220,7 @@ async def list_all_coupon_token_addresses(
220220
IDXCouponToken.initial_offering_status == initial_offering_status
221221
)
222222
count = await async_session.scalar(
223-
select(func.count()).select_from(stmt.subquery())
223+
stmt.with_only_columns(func.count()).order_by(None)
224224
)
225225

226226
if sort_item == "created":

0 commit comments

Comments
 (0)