【解決方法】ルックアップオペレーションスプリングブートで実行時間を最適化する方法


単一のテーブルからフェッチするときに MongoDB で 50.0M を超えるドキュメントを検索するスプリング ブート プロジェクトを作成していますが、問題は 2 つのテーブルを結合して別のテーブルの顧客ステータスを確認する場合です。実行時間は最大10分かかりますが、これは非常に嫌なことです。これは私が持っているコードです。

私が試したこと:

コントローラ クラス

@RestController
@RequestMapping("/customer_api")
public class CustomerApi{

	@Autowired
	private CustomerService customerService;
	
	@GetMapping("/customer/{year}/{month}")
	protected int getCustomerByStatus(@PathVariable int year, @PathVariable int month) {
	return customerService.getCustomerByStatus(year,month);	
	}
}

サービスクラス

@Service
public class CustomerService {
	
	@Autowired
	private MongoTemplate mongoTemplate;
	
	public int getCustomerByStatus(int year, int month) {
		
	YearMonth yearMonth_ = YearMonth.of(year, month);
	LocalDate startDate = yearMonth_.atDay(1);
	LocalDate endDate = yearMonth_.atEndOfMonth();
	
	
	LookupOperation checkStatus = LookupOperation.newLookup().from("tbl_status")		                .localField("customerId").foreignField("customerId").as("customerStatus");
	
	AggregationOperation matchData = Aggregation.match(Criteria.where("customerCode").is("1")
			.andOperator(Criteria.where("orderDate").gte(startDate.toString()), Criteria.where("orderDate").lte(endDate.toString()),
		    Criteria.where("customerStatus.status").ne("Disabled"), Criteria.where("customerStatus.status").ne("Opted Out")));
	
Aggregation aggregation = Aggregation.newAggregation(checkStatus, matchData);
	
	var data = mongoTemplate.aggregate(aggregation, "tbl_customers", Customer.class).getMappedResults().size();
	return data;
	}

}

テーブル カスタマー

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "tbl_customers")
public class Customer {
	@Id
	private String _id;
	private String customerId;
	private String region;
	private String council;
	private String country;
	private String status;
	private String customerCode;
	private LocalDateTime fileCreation; 
	private String registeredBy;
}

テーブルのステータス

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "tbl_status")
public class DataFile {
	@Id
	private String _id;
	private String orderDetails;
	private String orderNumber;
	private String orderLocation;
	private String quantity;
	private String customerId;
	private LocalDateTime orderDate; 
}

どんな提案でも大歓迎です。

解決策 1

おそらくフィールドにインデックスを付けずに、「無効」と「オプトアウト」の2つの文字列を探しているため、永遠に時間がかかります。 これはおそらく、パフォーマンスの点でステータスを取得するための最悪の方法です。 整数値 (0、1、2、3、…) など、これらの状態の整数値を探している場合、クエリははるかに高速になります。 通常、データベース エンジンは文字列操作のパフォーマンスが高くなく、文字列の検索はそのカテゴリに分類されます。

適切な索引付けも役立ちます。

コメント

タイトルとURLをコピーしました