diff --git a/src/libs/zbxdbcache/dbconfig.c b/src/libs/zbxdbcache/dbconfig.c
index a0ffa05e3e..5ad77543f4 100644
--- a/src/libs/zbxdbcache/dbconfig.c
+++ b/src/libs/zbxdbcache/dbconfig.c
@@ -2880,7 +2880,6 @@ static void	DCsync_items(zbx_dbsync_t *sync, int flags)
 		if (0 == found)
 		{
 			item->triggers = NULL;
-			item->update_triggers = 0;
 			item->nextcheck = 0;
 			item->state = (unsigned char)atoi(row[12]);
 			ZBX_STR2UINT64(item->lastlogsize, row[20]);
@@ -3653,7 +3652,374 @@ static void	DCsync_prototype_items(zbx_dbsync_t *sync)
 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
 }
 
-static void	DCsync_triggers(zbx_dbsync_t *sync)
+/* item-trigger changes - to which triggers item was added and removed */
+typedef struct
+{
+	ZBX_DC_ITEM		*item;
+	zbx_vector_ptr_t	triggers_add;
+	zbx_vector_ptr_t	triggers_del;
+}
+zbx_dc_item_triggers_t;
+
+/* trigger update cache */
+typedef struct
+{
+	zbx_hashset_t		items_triggers;
+	zbx_vector_uint64_t	functionids;
+	zbx_vector_ptr_t	items;
+}
+zbx_dc_trigger_update_t;
+
+static zbx_hash_t	dc_item_triggers_hash_func(const void *d)
+{
+	const zbx_dc_item_triggers_t	*item_triggers = (const zbx_dc_item_triggers_t *)d;
+
+	return ZBX_DEFAULT_UINT64_HASH_FUNC(&item_triggers->item->itemid);
+}
+
+static int	dc_item_triggers_compare_func(const void *d1, const void *d2)
+{
+	const zbx_dc_item_triggers_t	*item_triggers1 = (const zbx_dc_item_triggers_t *)d1;
+	const zbx_dc_item_triggers_t	*item_triggers2 = (const zbx_dc_item_triggers_t *)d2;
+
+	ZBX_RETURN_IF_NOT_EQUAL(item_triggers1->item->itemid, item_triggers2->item->itemid);
+	return 0;
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: dc_trigger_update_init                                           *
+ *                                                                            *
+ * Purpose: initialize trigger update cache                                   *
+ *                                                                            *
+ ******************************************************************************/
+static void	dc_trigger_update_init(zbx_dc_trigger_update_t *update)
+{
+	zbx_hashset_create(&update->items_triggers, 10, dc_item_triggers_hash_func, dc_item_triggers_compare_func);
+	zbx_vector_uint64_create(&update->functionids);
+	zbx_vector_ptr_create(&update->items);
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: dc_trigger_update_init                                           *
+ *                                                                            *
+ * Purpose: clear trigger update cache                                        *
+ *                                                                            *
+ ******************************************************************************/
+
+static void	dc_trigger_update_clear(zbx_dc_trigger_update_t *update)
+{
+	zbx_hashset_iter_t	iter;
+	zbx_dc_item_triggers_t	*item_triggers;
+
+	zbx_hashset_iter_reset(&update->items_triggers, &iter);
+	while (NULL != (item_triggers = (zbx_dc_item_triggers_t *)zbx_hashset_iter_next(&iter)))
+	{
+		zbx_vector_ptr_destroy(&item_triggers->triggers_add);
+		zbx_vector_ptr_destroy(&item_triggers->triggers_del);
+	}
+	zbx_hashset_destroy(&update->items_triggers);
+
+	zbx_vector_uint64_destroy(&update->functionids);
+	zbx_vector_ptr_destroy(&update->items);
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: dc_trigger_update_get_item                                       *
+ *                                                                            *
+ * Purpose: get item trigger changes from update, add cache if necessary      *
+ *                                                                            *
+ ******************************************************************************/
+static zbx_dc_item_triggers_t	*dc_trigger_update_get_item(zbx_dc_trigger_update_t *update, ZBX_DC_ITEM *item)
+{
+	zbx_dc_item_triggers_t	*item_triggers;
+
+	if (NULL == (item_triggers = (zbx_dc_item_triggers_t *)zbx_hashset_search(&update->items_triggers, &item)))
+	{
+		zbx_dc_item_triggers_t	item_triggers_local;
+
+		item_triggers_local.item = item;
+		item_triggers = (zbx_dc_item_triggers_t *)zbx_hashset_insert(&update->items_triggers,
+				&item_triggers_local, sizeof(item_triggers_local));
+		zbx_vector_ptr_create(&item_triggers->triggers_add);
+		zbx_vector_ptr_create(&item_triggers->triggers_del);
+	}
+
+	return item_triggers;
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: dc_trigger_update_add_item                                       *
+ *                                                                            *
+ * Purpose: register item adding to trigger in update cache                   *
+ *                                                                            *
+ ******************************************************************************/
+static void	dc_trigger_update_add_item(zbx_dc_trigger_update_t *update, ZBX_DC_TRIGGER *trigger, ZBX_DC_ITEM *item)
+{
+	zbx_dc_item_triggers_t	*item_triggers;
+
+	item_triggers = dc_trigger_update_get_item(update, item);
+	zbx_vector_ptr_append(&item_triggers->triggers_add, trigger);
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: dc_trigger_update_add_item                                       *
+ *                                                                            *
+ * Purpose: register item removal from trigger in update cache                *
+ *                                                                            *
+ ******************************************************************************/
+static void	dc_trigger_update_del_item(zbx_dc_trigger_update_t *update, ZBX_DC_TRIGGER *trigger, zbx_uint64_t itemid)
+{
+	zbx_dc_item_triggers_t	*item_triggers;
+	ZBX_DC_ITEM 		*item;
+
+	if (NULL == (item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &itemid)))
+		return;
+
+	item_triggers = dc_trigger_update_get_item(update, item);
+	zbx_vector_ptr_append(&item_triggers->triggers_del, trigger);
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: dc_trigger_update_get_items                                      *
+ *                                                                            *
+ * Purpose: get items used in trigger expression/recovery expression          *
+ *                                                                            *
+ ******************************************************************************/
+static void	dc_trigger_update_get_items(zbx_dc_trigger_update_t *update, ZBX_DC_TRIGGER *trigger)
+{
+	int		i;
+	ZBX_DC_FUNCTION	*function;
+	ZBX_DC_ITEM	*item;
+
+	if (NULL != trigger->expression_bin)
+	{
+		zbx_get_serialized_expression_functionids(trigger->expression, trigger->expression_bin,
+				&update->functionids);
+	}
+
+	if (TRIGGER_RECOVERY_MODE_RECOVERY_EXPRESSION == trigger->recovery_mode &&
+			NULL != trigger->recovery_expression_bin)
+	{
+		zbx_get_serialized_expression_functionids(trigger->recovery_expression,
+				trigger->recovery_expression_bin, &update->functionids);
+	}
+
+	zbx_vector_uint64_sort(&update->functionids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+	zbx_vector_uint64_uniq(&update->functionids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+	for (i = 0; i < update->functionids.values_num; i++)
+	{
+		if (NULL == (function = (ZBX_DC_FUNCTION *)zbx_hashset_search(&config->functions,
+				&update->functionids.values[i])))
+		{
+			continue;
+		}
+
+		if (NULL == (item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &function->itemid)))
+			continue;
+
+		zbx_vector_ptr_append(&update->items, item);
+	}
+
+	zbx_vector_ptr_sort(&update->items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
+	zbx_vector_ptr_uniq(&update->items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
+
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: dc_trigger_update_merge_items                                    *
+ *                                                                            *
+ * Purpose: compare old item list used by trigger with new, register          *
+ *          item-trigger changes if item was 'added/removed' to trigger       *
+ *                                                                            *
+ ******************************************************************************/
+static void	dc_trigger_update_merge_items(zbx_dc_trigger_update_t *update, ZBX_DC_TRIGGER *trigger)
+{
+	int		i;
+	ZBX_DC_ITEM	*item;
+	zbx_uint64_t	*itemid;
+
+	dc_trigger_update_get_items(update, trigger);
+
+	for (itemid = trigger->itemids, i = 0; 0 != *itemid && i < update->items.values_num; )
+	{
+		item = (ZBX_DC_ITEM *)update->items.values[i];
+
+		if (*itemid == item->itemid)
+		{
+			itemid++;
+			i++;
+			continue;
+		}
+
+		if (*itemid < item->itemid)
+		{
+			dc_trigger_update_del_item(update, trigger, *itemid);
+			itemid++;
+		}
+		else
+		{
+			dc_trigger_update_add_item(update, trigger, item);
+			i++;
+		}
+	}
+
+	if (i != update->items.values_num)
+	{
+		for (; i < update->items.values_num; i++)
+			dc_trigger_update_add_item(update, trigger, (ZBX_DC_ITEM *)update->items.values[i]);
+
+		trigger->itemids = (zbx_uint64_t *)__config_mem_realloc_func(trigger->itemids, sizeof(zbx_uint64_t)  *
+				(size_t)(size_t)(update->items.values_num + 1));
+	}
+	else
+	{
+		for (; 0 != *itemid; itemid++)
+			dc_trigger_update_del_item(update, trigger, *itemid);
+	}
+
+	for (i = 0; i < update->items.values_num; i++)
+		trigger->itemids[i] = ((ZBX_DC_ITEM *)update->items.values[i])->itemid;
+
+	trigger->itemids[i] = 0;
+
+	zbx_vector_uint64_clear(&update->functionids);
+	zbx_vector_ptr_clear(&update->items);
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: dc_trigger_update_add_items                                      *
+ *                                                                            *
+ * Purpose: add items to trigger and register item-trigger changes            *
+ *                                                                            *
+ ******************************************************************************/
+static void	dc_trigger_update_add_items(zbx_dc_trigger_update_t *update, ZBX_DC_TRIGGER *trigger)
+{
+	dc_trigger_update_get_items(update, trigger);
+
+	if (0 != update->items.values_num)
+	{
+		int	i;
+
+		trigger->itemids = (zbx_uint64_t *)__config_mem_malloc_func(NULL, sizeof(zbx_uint64_t) *
+				(size_t)(update->items.values_num + 1));
+
+		for (i = 0; i < update->items.values_num; i++)
+		{
+			ZBX_DC_ITEM	*item = (ZBX_DC_ITEM *)update->items.values[i];
+
+			trigger->itemids[i] = item->itemid;
+			dc_trigger_update_add_item(update, trigger, item);
+		}
+
+		trigger->itemids[i] = 0;
+		zbx_vector_ptr_clear(&update->items);
+	}
+
+	zbx_vector_uint64_clear(&update->functionids);
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: dc_trigger_update_del_items                                      *
+ *                                                                            *
+ * Purpose: remove items from trigger and register item-trigger changes       *
+ *                                                                            *
+ ******************************************************************************/
+static void	dc_trigger_update_del_items(zbx_dc_trigger_update_t *update, ZBX_DC_TRIGGER *trigger)
+{
+	zbx_uint64_t	*itemid;
+
+	if (NULL == trigger->itemids)
+		return;
+
+	for (itemid = trigger->itemids; 0 != *itemid; itemid++)
+		dc_trigger_update_del_item(update, trigger, *itemid);
+
+	__config_mem_free_func(trigger->itemids);
+}
+
+/******************************************************************************
+ *                                                                            *
+ * Function: dc_trigger_update_sync_items                                     *
+ *                                                                            *
+ * Purpose: apply item-trigger changes to items (update item->triggers array) *
+ *                                                                            *
+ ******************************************************************************/
+static void	dc_trigger_update_sync_items(zbx_dc_trigger_update_t *update)
+{
+	zbx_hashset_iter_t	iter;
+	zbx_dc_item_triggers_t	*item_triggers;
+	int			i;
+
+	zbx_hashset_iter_reset(&update->items_triggers, &iter);
+	while (NULL != (item_triggers = (zbx_dc_item_triggers_t *)zbx_hashset_iter_next(&iter)))
+	{
+		int		next, triggers_num = 0, inc;
+		ZBX_DC_TRIGGER	**trigger;
+
+		if (NULL != item_triggers->item->triggers)
+		{
+			int	last;
+
+			for (trigger = item_triggers->item->triggers; NULL != *trigger; trigger++)
+				triggers_num++;
+
+			last = triggers_num - 1;
+
+			/* remove deleted triggers */
+
+			for (i = 0; i < item_triggers->triggers_del.values_num; i++)
+			{
+				for (trigger = item_triggers->item->triggers; NULL != trigger; trigger++)
+				{
+					if (*trigger == item_triggers->triggers_del.values[i])
+					{
+						*trigger = item_triggers->item->triggers[last--];
+						break;
+					}
+				}
+			}
+
+			next = last + 1;
+		}
+		else
+			next = 0;
+
+		/* append added triggers */
+
+		inc = item_triggers->triggers_add.values_num - item_triggers->triggers_del.values_num;
+
+		if (0 < inc)
+		{
+			triggers_num += inc;
+			item_triggers->item->triggers = __config_mem_realloc_func(item_triggers->item->triggers,
+					(size_t)(triggers_num + 1) * sizeof(ZBX_DC_TRIGGER *));
+		}
+
+		for (i = 0; i < item_triggers->triggers_add.values_num; i++)
+			item_triggers->item->triggers[next++] = item_triggers->triggers_add.values[i];
+
+		if (0 == next)
+		{
+			__config_mem_free_func(item_triggers->item->triggers);
+			item_triggers->item->triggers = NULL;
+		}
+		else
+			item_triggers->item->triggers[next] = NULL;
+
+	}
+}
+
+static void	DCsync_triggers(zbx_dbsync_t *sync, zbx_vector_uint64_t *triggerids)
 {
 	char		**row;
 	zbx_uint64_t	rowid;
@@ -3661,11 +4027,15 @@ static void	DCsync_triggers(zbx_dbsync_t *sync)
 
 	ZBX_DC_TRIGGER	*trigger;
 
-	int		found, ret;
+	int		i, index = 0, found, ret;
 	zbx_uint64_t	triggerid;
 
+	zbx_dc_trigger_update_t	update;
+
 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
 
+	dc_trigger_update_init(&update);
+
 	while (SUCCEED == (ret = zbx_dbsync_next(sync, &rowid, &row, &tag)))
 	{
 		/* removed rows will be always added at the end */
@@ -3702,6 +4072,7 @@ static void	DCsync_triggers(zbx_dbsync_t *sync)
 			zbx_vector_ptr_create_ext(&trigger->tags, __config_mem_malloc_func, __config_mem_realloc_func,
 					__config_mem_free_func);
 			trigger->topoindex = 1;
+			trigger->itemids = NULL;
 		}
 		else
 		{
@@ -3715,54 +4086,30 @@ static void	DCsync_triggers(zbx_dbsync_t *sync)
 		trigger->recovery_expression_bin = config_decode_serialized_expression(row[17]);
 		trigger->timer = atoi(row[18]);
 		trigger->revision = config->sync_start_ts;
+
+		if (NULL == trigger->itemids)
+			dc_trigger_update_add_items(&update, trigger);
+		else
+			dc_trigger_update_merge_items(&update, trigger);
+
+		while (index < triggerids->values_num && triggerids->values[index] < triggerid)
+			index++;
+
+		/* mark trigger as processed */
+		if (triggerids->values[index] == triggerid)
+			triggerids->values[index++] = 0;
+
 	}
 
 	/* remove deleted triggers from buffer */
 	if (SUCCEED == ret)
 	{
-		zbx_vector_uint64_t	functionids;
-		int			i;
-		ZBX_DC_ITEM		*item;
-		ZBX_DC_FUNCTION		*function;
-
-		zbx_vector_uint64_create(&functionids);
-
 		for (; SUCCEED == ret; ret = zbx_dbsync_next(sync, &rowid, &row, &tag))
 		{
 			if (NULL == (trigger = (ZBX_DC_TRIGGER *)zbx_hashset_search(&config->triggers, &rowid)))
 				continue;
 
-			/* force trigger list update for items used in removed trigger */
-
-			if (NULL != trigger->expression_bin)
-			{
-				zbx_get_serialized_expression_functionids(trigger->expression, trigger->expression_bin,
-						&functionids);
-			}
-
-			if (TRIGGER_RECOVERY_MODE_RECOVERY_EXPRESSION == trigger->recovery_mode &&
-					NULL != trigger->recovery_expression_bin)
-			{
-				zbx_get_serialized_expression_functionids(trigger->recovery_expression,
-						trigger->recovery_expression_bin, &functionids);
-			}
-
-			for (i = 0; i < functionids.values_num; i++)
-			{
-				if (NULL == (function = (ZBX_DC_FUNCTION *)zbx_hashset_search(&config->functions, &functionids.values[i])))
-					continue;
-
-				if (NULL == (item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &function->itemid)))
-					continue;
-
-				item->update_triggers = 1;
-				if (NULL != item->triggers)
-				{
-					config->items.mem_free_func(item->triggers);
-					item->triggers = NULL;
-				}
-			}
-			zbx_vector_uint64_clear(&functionids);
+			dc_trigger_update_del_items(&update, trigger);
 
 			zbx_strpool_release(trigger->description);
 			zbx_strpool_release(trigger->expression);
@@ -3781,9 +4128,26 @@ static void	DCsync_triggers(zbx_dbsync_t *sync)
 
 			zbx_hashset_remove_direct(&config->triggers, trigger);
 		}
-		zbx_vector_uint64_destroy(&functionids);
 	}
 
+	for (i = 0; i < triggerids->values_num; i++)
+	{
+		/* trigger has been already processed */
+		if (0 == triggerids->values[i])
+			continue;
+
+		if (NULL == (trigger = (ZBX_DC_TRIGGER *)zbx_hashset_search(&config->triggers, &rowid)))
+			continue;
+
+		if (NULL == trigger->itemids)
+			dc_trigger_update_add_items(&update, trigger);
+		else
+			dc_trigger_update_merge_items(&update, trigger);
+	}
+
+	dc_trigger_update_sync_items(&update);
+	dc_trigger_update_clear(&update);
+
 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
 }
 
@@ -4221,7 +4585,7 @@ static void	dc_schedule_trigger_timers(zbx_hashset_t *trend_queue, int now)
 	}
 }
 
-static void	DCsync_functions(zbx_dbsync_t *sync)
+static void	DCsync_functions(zbx_dbsync_t *sync, zbx_vector_uint64_t *triggerids)
 {
 	char		**row;
 	zbx_uint64_t	rowid;
@@ -4260,24 +4624,7 @@ static void	DCsync_functions(zbx_dbsync_t *sync)
 
 		function = (ZBX_DC_FUNCTION *)DCfind_id(&config->functions, functionid, sizeof(ZBX_DC_FUNCTION), &found);
 
-		if (1 == found)
-		{
-			if (function->itemid != itemid)
-			{
-				ZBX_DC_ITEM	*item_last;
-
-				if (NULL != (item_last = zbx_hashset_search(&config->items, &function->itemid)))
-				{
-					item_last->update_triggers = 1;
-					if (NULL != item_last->triggers)
-					{
-						config->items.mem_free_func(item_last->triggers);
-						item_last->triggers = NULL;
-					}
-				}
-			}
-		}
-		else
+		if (0 == found)
 			function->timer_revision = 0;
 
 		function->triggerid = triggerid;
@@ -4288,9 +4635,7 @@ static void	DCsync_functions(zbx_dbsync_t *sync)
 		function->type = zbx_get_function_type(function->function);
 		function->revision = config->sync_start_ts;
 
-		item->update_triggers = 1;
-		if (NULL != item->triggers)
-			item->triggers[0] = NULL;
+		zbx_vector_uint64_append(triggerids, triggerid);
 	}
 
 	for (; SUCCEED == ret; ret = zbx_dbsync_next(sync, &rowid, &row, &tag))
@@ -4298,22 +4643,15 @@ static void	DCsync_functions(zbx_dbsync_t *sync)
 		if (NULL == (function = (ZBX_DC_FUNCTION *)zbx_hashset_search(&config->functions, &rowid)))
 			continue;
 
-		if (NULL != (item = (ZBX_DC_ITEM *)zbx_hashset_search(&config->items, &function->itemid)))
-		{
-			item->update_triggers = 1;
-			if (NULL != item->triggers)
-			{
-				config->items.mem_free_func(item->triggers);
-				item->triggers = NULL;
-			}
-		}
-
 		zbx_strpool_release(function->function);
 		zbx_strpool_release(function->parameter);
 
 		zbx_hashset_remove_direct(&config->functions, function);
 	}
 
+	zbx_vector_uint64_sort(triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+	zbx_vector_uint64_uniq(triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
 	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
 }
 
@@ -5758,17 +6096,6 @@ static void	dc_trigger_update_topology(void)
 	DCconfig_sort_triggers_topologically();
 }
 
-static int	zbx_default_ptr_pair_ptr_compare_func(const void *d1, const void *d2)
-{
-	const zbx_ptr_pair_t	*p1 = (const zbx_ptr_pair_t *)d1;
-	const zbx_ptr_pair_t	*p2 = (const zbx_ptr_pair_t *)d2;
-
-	ZBX_RETURN_IF_NOT_EQUAL(p1->first, p2->first);
-	ZBX_RETURN_IF_NOT_EQUAL(p1->second, p2->second);
-
-	return 0;
-}
-
 /******************************************************************************
  *                                                                            *
  * Function: dc_trigger_update_cache                                          *
@@ -5786,16 +6113,12 @@ static void	dc_trigger_update_cache(void)
 	ZBX_DC_TRIGGER		*trigger;
 	ZBX_DC_FUNCTION		*function;
 	ZBX_DC_ITEM		*item;
-	int			i, j, k;
-	zbx_ptr_pair_t		itemtrig;
-	zbx_vector_ptr_pair_t	itemtrigs;
 	ZBX_DC_HOST		*host;
 
 	zbx_hashset_iter_reset(&config->triggers, &iter);
 	while (NULL != (trigger = (ZBX_DC_TRIGGER *)zbx_hashset_iter_next(&iter)))
 		trigger->functional = TRIGGER_FUNCTIONAL_TRUE;
 
-	zbx_vector_ptr_pair_create(&itemtrigs);
 	zbx_hashset_iter_reset(&config->functions, &iter);
 	while (NULL != (function = (ZBX_DC_FUNCTION *)zbx_hashset_iter_next(&iter)))
 	{
@@ -5806,14 +6129,6 @@ static void	dc_trigger_update_cache(void)
 			continue;
 		}
 
-		/* cache item - trigger link */
-		if (0 != item->update_triggers)
-		{
-			itemtrig.first = item;
-			itemtrig.second = trigger;
-			zbx_vector_ptr_pair_append(&itemtrigs, itemtrig);
-		}
-
 		/* disable functionality for triggers with expression containing */
 		/* disabled or not monitored items                               */
 
@@ -5827,32 +6142,6 @@ static void	dc_trigger_update_cache(void)
 			trigger->functional = TRIGGER_FUNCTIONAL_FALSE;
 		}
 	}
-
-	zbx_vector_ptr_pair_sort(&itemtrigs, zbx_default_ptr_pair_ptr_compare_func);
-	zbx_vector_ptr_pair_uniq(&itemtrigs, zbx_default_ptr_pair_ptr_compare_func);
-
-	/* update links from items to triggers */
-	for (i = 0; i < itemtrigs.values_num; i++)
-	{
-		for (j = i + 1; j < itemtrigs.values_num; j++)
-		{
-			if (itemtrigs.values[i].first != itemtrigs.values[j].first)
-				break;
-		}
-
-		item = (ZBX_DC_ITEM *)itemtrigs.values[i].first;
-		item->update_triggers = 0;
-		item->triggers = (ZBX_DC_TRIGGER **)config->items.mem_realloc_func(item->triggers, (j - i + 1) * sizeof(ZBX_DC_TRIGGER *));
-
-		for (k = i; k < j; k++)
-			item->triggers[k - i] = (ZBX_DC_TRIGGER *)itemtrigs.values[k].second;
-
-		item->triggers[j - i] = NULL;
-
-		i = j - 1;
-	}
-
-	zbx_vector_ptr_pair_destroy(&itemtrigs);
 }
 
 /******************************************************************************
@@ -5955,6 +6244,7 @@ void	DCsync_configuration(unsigned char mode, const struct zbx_json_parse *jp_kv
 	zbx_uint64_t	update_flags = 0;
 
 	zbx_hashset_t		trend_queue;
+	zbx_vector_uint64_t	triggerids;
 
 	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
 
@@ -6015,6 +6305,8 @@ void	DCsync_configuration(unsigned char mode, const struct zbx_json_parse *jp_kv
 	zbx_dbsync_init(&maintenance_group_sync, mode);
 	zbx_dbsync_init(&maintenance_host_sync, mode);
 
+	zbx_vector_uint64_create(&triggerids);
+
 	sec = zbx_time();
 	if (FAIL == zbx_dbsync_compare_config(&config_sync))
 		goto out;
@@ -6224,7 +6516,7 @@ void	DCsync_configuration(unsigned char mode, const struct zbx_json_parse *jp_kv
 
 	START_SYNC;
 	sec = zbx_time();
-	DCsync_functions(&func_sync);
+	DCsync_functions(&func_sync, &triggerids);
 	fsec2 = zbx_time() - sec;
 	FINISH_SYNC;
 
@@ -6283,7 +6575,7 @@ void	DCsync_configuration(unsigned char mode, const struct zbx_json_parse *jp_kv
 	START_SYNC;
 
 	sec = zbx_time();
-	DCsync_triggers(&triggers_sync);
+	DCsync_triggers(&triggers_sync, &triggerids);
 	tsec2 = zbx_time() - sec;
 
 	sec = zbx_time();
@@ -6634,6 +6926,8 @@ out:
 
 	FINISH_SYNC;
 
+	zbx_vector_uint64_destroy(&triggerids);
+
 	zbx_dbsync_clear(&config_sync);
 	zbx_dbsync_clear(&autoreg_config_sync);
 	zbx_dbsync_clear(&hosts_sync);
diff --git a/src/libs/zbxdbcache/dbconfig.h b/src/libs/zbxdbcache/dbconfig.h
index f1c3b36025..f9fff74a8b 100644
--- a/src/libs/zbxdbcache/dbconfig.h
+++ b/src/libs/zbxdbcache/dbconfig.h
@@ -51,6 +51,8 @@ typedef struct
 	unsigned char		correlation_mode;	/* see ZBX_TRIGGER_CORRELATION_* defines */
 	unsigned char		timer;
 
+	zbx_uint64_t		*itemids;		/* 0 terminated array of itemids used in trigger */
+							/* expression and cached in config cache         */
 	zbx_vector_ptr_t	tags;
 }
 ZBX_DC_TRIGGER;
@@ -111,7 +113,6 @@ typedef struct
 	unsigned char		status;
 	unsigned char		queue_priority;
 	unsigned char		schedulable;
-	unsigned char		update_triggers;
 	zbx_uint64_t		templateid;
 	zbx_uint64_t		parent_itemid; /* from joined item_discovery table */
 
diff --git a/src/libs/zbxdbcache/dbsync.c b/src/libs/zbxdbcache/dbsync.c
index ee3a69a7c8..2a64cada39 100644
--- a/src/libs/zbxdbcache/dbsync.c
+++ b/src/libs/zbxdbcache/dbsync.c
@@ -2358,7 +2358,8 @@ int	zbx_dbsync_compare_triggers(zbx_dbsync_t *sync)
 				" and i.itemid=f.itemid"
 				" and f.triggerid=t.triggerid"
 				" and h.status in (%d,%d)"
-				" and t.flags<>%d",
+				" and t.flags<>%d"
+			 " order by triggerid",
 			HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED,
 			ZBX_FLAG_DISCOVERY_PROTOTYPE)))
 	{
