# 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();
```