# 11. Производительность: кеш и TaggedCache

[← Оглавление](./index.md)

---

## Кеширование через Bitrix\Main\Data\Cache

**ПЛОХО — ДОРОГОЙ ЗАПРОС БЕЗ КЕША**
```php
// Выполняется на каждый запрос страницы
$elements = \CIBlockElement::GetList(
    [], ['IBLOCK_ID' => $iblockId], false, false,
    ['ID','NAME']
)->FetchAll();
```

**ХОРОШО — РЕЗУЛЬТАТ КЕШИРУЕТСЯ**
```php
$cache = \Bitrix\Main\Data\Cache::createInstance();
$cacheId = 'iblock_elements_' . $iblockId;

if ($cache->initCache(3600, $cacheId, '/my_module/')) {
    $elements = $cache->getVars();
} elseif ($cache->startDataCache()) {
    $elements = \Bitrix\Iblock\Elements\ElementNewsTable::getList([
        'filter' => ['IBLOCK_ID' => $iblockId],
    ])->fetchAll();
    $cache->endDataCache($elements);
}
```

---

## Тегированный кеш (TaggedCache)

TaggedCache позволяет инвалидировать кеш при изменении конкретных сущностей. Предпочтительный подход для данных CRM и Iblock.

**ПЛОХО — СБРОС ВСЕГО КЕША ПРИ ИЗМЕНЕНИИ ОДНОГО ЛИДА**
```php
// При любом изменении сбрасываем весь кеш модуля
\Bitrix\Main\Data\Cache::createInstance()->cleanDir('/crm/leads/');
```

**ХОРОШО — ТОЧЕЧНАЯ ИНВАЛИДАЦИЯ ПО ТЕГУ**
```php
$taggedCache = \Bitrix\Main\Application::getInstance()->getTaggedCache();
$cache = \Bitrix\Main\Data\Cache::createInstance();

if ($cache->initCache(3600, 'lead_' . $leadId, '/crm/leads/')) {
    $data = $cache->getVars();
} elseif ($cache->startDataCache()) {
    $taggedCache->startTagCache('/crm/leads/');
    $taggedCache->registerTag('crm_lead_' . $leadId);
    $taggedCache->registerTag('crm_leads_list');
    $data = $this->leadRepository->getById($leadId);
    $taggedCache->endTagCache();
    $cache->endDataCache($data);
}

// При изменении лида — только его кеш:
$taggedCache->clearByTag('crm_lead_' . $leadId);

// При массовом изменении:
$taggedCache->clearByTag('crm_leads_list');
```

---

## Выбирайте только нужные поля

**ПЛОХО — SELECT * БЕЗ НЕОБХОДИМОСТИ**
```php
$leads = \Bitrix\Crm\LeadTable::getList(['select' => ['*']])->fetchAll();
```

**ХОРОШО — ТОЛЬКО НЕОБХОДИМЫЕ ПОЛЯ**
```php
$leads = \Bitrix\Crm\LeadTable::query()
    ->setSelect(['ID', 'TITLE', 'STATUS_ID', 'DATE_CREATE'])
    ->setLimit(50)
    ->exec()->fetchAll();
```