diff --git a/src/zabbix_server/lld/lld_host.c b/src/zabbix_server/lld/lld_host.c
index b6eda0bca56..34b42f4d2e8 100644
--- a/src/zabbix_server/lld/lld_host.c
+++ b/src/zabbix_server/lld/lld_host.c
@@ -338,6 +338,13 @@ zbx_lld_host_t;
 ZBX_PTR_VECTOR_DECL(lld_host_ptr, zbx_lld_host_t*)
 ZBX_PTR_VECTOR_IMPL(lld_host_ptr, zbx_lld_host_t*)
 
+typedef struct
+{
+	const char	*host_proto;
+	zbx_hashset_t	host_hosts;
+}
+zbx_lld_proto_host_hosts_t;
+
 static int	lld_host_compare_func(const void *d1, const void *d2)
 {
 	const zbx_lld_host_t	*host_1 = *(const zbx_lld_host_t * const *)d1;
@@ -763,6 +770,21 @@ static void	lld_hosts_get(zbx_uint64_t parent_hostid, zbx_vector_lld_host_ptr_t
 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
 }
 
+static zbx_hash_t	lld_proto_host_host_hash(const void *d)
+{
+	const zbx_lld_proto_host_hosts_t	*host = (zbx_lld_proto_host_hosts_t *)d;
+
+	return ZBX_DEFAULT_STRING_HASH_FUNC(host->host_proto);
+}
+
+static int	lld_proto_host_host_compare(const void *d1, const void *d2)
+{
+	const zbx_lld_proto_host_hosts_t	*host1 = (zbx_lld_proto_host_hosts_t *)d1;
+	const zbx_lld_proto_host_hosts_t	*host2 = (zbx_lld_proto_host_hosts_t *)d2;
+
+	return strcmp(host1->host_proto, host2->host_proto);
+}
+
 static zbx_hash_t	lld_host_host_hash(const void *d)
 {
 	const zbx_lld_host_t	*host = *(const zbx_lld_host_t *const *)d;
@@ -1097,43 +1119,42 @@ static void	lld_hosts_validate(zbx_vector_lld_host_ptr_t *hosts, int dflags, cha
 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
 }
 
-static zbx_lld_host_t	*lld_host_make(zbx_vector_lld_host_ptr_t *hosts, zbx_vector_lld_host_ptr_t *hosts_old,
+static zbx_lld_host_t	*lld_host_make(zbx_vector_lld_host_ptr_t *hosts, zbx_hashset_t *proto_host_hosts,
 		const char *host_proto, const char *name_proto,
 		signed char inventory_mode_proto, unsigned char status_proto, unsigned char discover_proto,
 		zbx_vector_db_tag_ptr_t *tags, const zbx_lld_row_t *lld_row, unsigned char custom_iface,
 		int dflags, char **error)
 {
-	char			*buffer = NULL;
-	int			host_found = 0;
-	zbx_lld_host_t		*host = NULL;
-	zbx_vector_db_tag_ptr_t	override_tags;
-	zbx_vector_uint64_t	lnk_templateids;
-	zbx_vector_db_tag_ptr_t	new_tags;
+	char				*buffer = NULL;
+	int				host_found = 0;
+	zbx_lld_host_t			*host = NULL;
+	zbx_vector_db_tag_ptr_t		override_tags;
+	zbx_vector_uint64_t		lnk_templateids;
+	zbx_vector_db_tag_ptr_t		new_tags;
+	zbx_lld_proto_host_hosts_t	*proto_host_host;
+	zbx_hashset_iter_t		iter;
 
 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
 
 	zbx_vector_uint64_create(&lnk_templateids);
 	zbx_vector_db_tag_ptr_create(&new_tags);
 
-	for (int i = 0; i < hosts_old->values_num; i++)
+	zbx_hashset_iter_reset(proto_host_hosts, &iter);
+	while (NULL != (proto_host_host = (zbx_lld_proto_host_hosts_t *)zbx_hashset_iter_next(&iter)))
 	{
-		host = hosts_old->values[i];
-
-		if (0 != (host->flags & ZBX_FLAG_LLD_HOST_DISCOVERED))
-			continue;
+		zbx_lld_host_t	host_local, *phost_local = &host_local, **phost;
 
-		if (0 == host->hostid)
-			continue;
-
-		buffer = zbx_strdup(buffer, host->host_proto);
+		buffer = zbx_strdup(buffer, proto_host_host->host_proto);
 		zbx_substitute_lld_macros(&buffer, lld_row->data, ZBX_MACRO_ANY, NULL, 0);
 		zbx_lrtrim(buffer, ZBX_WHITESPACE);
 
-		if (0 == strcmp(host->host, buffer))
+		host_local.host = buffer;
+
+		if (NULL != (phost = zbx_hashset_search(&proto_host_host->host_hosts, &phost_local)))
 		{
-			zbx_vector_lld_host_ptr_remove(hosts_old, i);
 			host_found = 1;
-			break;
+			host = *phost;
+			zbx_hashset_remove_direct(&proto_host_host->host_hosts, phost);
 		}
 	}
 
@@ -6512,6 +6533,40 @@ out:
 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
 }
 
+static void	lld_prepare_proto_host_hosts(zbx_hashset_t *proto_host_hosts, zbx_vector_lld_host_ptr_t *hosts)
+{
+	for (int i = 0; i < hosts->values_num; i++)
+	{
+		zbx_lld_host_t			*host = hosts->values[i];
+		zbx_lld_proto_host_hosts_t	*proto_host_host_ptr, proto_host_host_local =
+						{.host_proto = host->host_proto};
+		int				num = proto_host_hosts->num_data;
+
+		if (0 != (host->flags & ZBX_FLAG_LLD_HOST_DISCOVERED))
+			continue;
+
+		if (0 == host->hostid)
+			continue;
+
+		proto_host_host_ptr = zbx_hashset_insert(proto_host_hosts, &proto_host_host_local,
+				sizeof(proto_host_host_local));
+
+		if (num != proto_host_hosts->num_data)
+		{
+			zbx_hashset_create(&proto_host_host_ptr->host_hosts, (size_t)hosts->values_num,
+					lld_host_host_hash, lld_host_host_compare);
+		}
+
+		zbx_hashset_insert(&proto_host_host_ptr->host_hosts, &host, sizeof(zbx_lld_host_t *));
+	}
+}
+
+static void	lld_proto_host_host_hash_clear(void *data)
+{
+	zbx_lld_proto_host_hosts_t	*lld_proto_host_host = (zbx_lld_proto_host_hosts_t *)data;
+	zbx_hashset_destroy(&lld_proto_host_host->host_hosts);
+}
+
 /******************************************************************************
  *                                                                            *
  * Purpose: adds or updates LLD hosts                                         *
@@ -6523,6 +6578,7 @@ void	lld_update_hosts(zbx_uint64_t lld_ruleid, const zbx_vector_lld_row_ptr_t *l
 {
 	zbx_db_result_t				result;
 	zbx_db_row_t				row;
+	zbx_hashset_t				proto_host_hosts;
 	zbx_vector_lld_host_ptr_t		hosts, hosts_old;
 	zbx_vector_lld_group_prototype_ptr_t	group_prototypes;
 	zbx_vector_lld_interface_ptr_t		interfaces;
@@ -6603,6 +6659,10 @@ void	lld_update_hosts(zbx_uint64_t lld_ruleid, const zbx_vector_lld_row_ptr_t *l
 	lld_interfaces_get(lld_ruleid, &interfaces, 0);
 	lld_masterhostmacros_get(lld_ruleid, &masterhostmacros);
 
+	zbx_hashset_create_ext(&proto_host_hosts, 10, lld_proto_host_host_hash,
+			lld_proto_host_host_compare, lld_proto_host_host_hash_clear,
+			ZBX_DEFAULT_MEM_MALLOC_FUNC, ZBX_DEFAULT_MEM_REALLOC_FUNC, ZBX_DEFAULT_MEM_FREE_FUNC);
+
 	result = zbx_db_select(
 			"select h.hostid,h.host,h.name,h.status,h.discover,hi.inventory_mode,h.custom_interfaces"
 			" from hosts h,host_discovery hd"
@@ -6640,7 +6700,7 @@ void	lld_update_hosts(zbx_uint64_t lld_ruleid, const zbx_vector_lld_row_ptr_t *l
 		if (0 != hosts.values_num)
 		{
 			lld_hosts_get_tags(&hosts);
-			zbx_vector_lld_host_ptr_append_array(&hosts_old, hosts.values, hosts.values_num);
+			lld_prepare_proto_host_hosts(&proto_host_hosts, &hosts);
 		}
 
 		lld_proto_tags_get(parent_hostid, &tags);
@@ -6665,7 +6725,7 @@ void	lld_update_hosts(zbx_uint64_t lld_ruleid, const zbx_vector_lld_row_ptr_t *l
 		{
 			const zbx_lld_row_t	*lld_row = lld_rows->values[i];
 
-			if (NULL == (host = lld_host_make(&hosts, &hosts_old, host_proto, name_proto,
+			if (NULL == (host = lld_host_make(&hosts, &proto_host_hosts, host_proto, name_proto,
 					inventory_mode_proto, status, discover, &tags, lld_row, use_custom_interfaces,
 					dflags | ZBX_FLAG_DISCOVERY_CREATED, error)))
 			{
@@ -6746,6 +6806,7 @@ void	lld_update_hosts(zbx_uint64_t lld_ruleid, const zbx_vector_lld_row_ptr_t *l
 		zbx_vector_lld_group_prototype_ptr_clear_ext(&group_prototypes, lld_group_prototype_free);
 		zbx_vector_lld_host_ptr_clear_ext(&hosts, lld_host_free);
 		zbx_vector_lld_host_ptr_clear(&hosts_old);
+		zbx_hashset_clear(&proto_host_hosts);
 
 		zbx_vector_uint64_clear(&groupids);
 		zbx_vector_uint64_clear(&del_hostgroupids);
@@ -6782,6 +6843,7 @@ void	lld_update_hosts(zbx_uint64_t lld_ruleid, const zbx_vector_lld_row_ptr_t *l
 	zbx_vector_uint64_destroy(&groupids);
 	zbx_vector_lld_host_ptr_destroy(&hosts);
 	zbx_vector_lld_host_ptr_destroy(&hosts_old);
+	zbx_hashset_destroy(&proto_host_hosts);
 
 	zbx_free(tls_psk);
 	zbx_free(tls_psk_identity);
