Merge pull request #36221 from s-aga-r/FIX-ISS-23-24-02079

perf: use `LEFT JOIN` instead of `NOT EXISTS`
diff --git a/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py b/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py
index 17b5aae..e986746 100644
--- a/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py
+++ b/erpnext/manufacturing/doctype/bom_update_log/bom_update_log.py
@@ -93,6 +93,7 @@
 		else:
 			frappe.enqueue(
 				method="erpnext.manufacturing.doctype.bom_update_log.bom_update_log.process_boms_cost_level_wise",
+				queue="long",
 				update_doc=self,
 				now=frappe.flags.in_test,
 				enqueue_after_commit=True,
diff --git a/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py b/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
index b90cfd9..a2919b7 100644
--- a/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
+++ b/erpnext/manufacturing/doctype/bom_update_log/bom_updation_utils.py
@@ -157,12 +157,19 @@
 def get_leaf_boms() -> List[str]:
 	"Get BOMs that have no dependencies."
 
-	return frappe.db.sql_list(
-		"""select name from `tabBOM` bom
-		where docstatus=1 and is_active=1
-			and not exists(select bom_no from `tabBOM Item`
-				where parent=bom.name and bom_no !='')"""
-	)
+	bom = frappe.qb.DocType("BOM")
+	bom_item = frappe.qb.DocType("BOM Item")
+
+	boms = (
+		frappe.qb.from_(bom)
+		.left_join(bom_item)
+		.on((bom.name == bom_item.parent) & (bom_item.bom_no != ""))
+		.select(bom.name)
+		.where((bom.docstatus == 1) & (bom.is_active == 1) & (bom_item.bom_no.isnull()))
+		.distinct()
+	).run(pluck=True)
+
+	return boms
 
 
 def _generate_dependence_map() -> defaultdict: