Optimizing 1C-Bitrix Infoblock Queries: Speed Up Your Catalog

Optimizing 1C-Bitrix Infoblock Queries: Speed Up Your Catalog ## Real Problem: Slow Infoblock Queries We often encounter projects where the Bitrix catalog slows down due to non-optimal infoblock queries. Typical scenario: a product listing page with 48 items takes 2-3 seconds to load, even whe

Our competencies:

Frequently Asked Questions

Optimizing 1C-Bitrix Infoblock Queries: Speed Up Your Catalog

Real Problem: Slow Infoblock Queries

We often encounter projects where the Bitrix catalog slows down due to non-optimal infoblock queries. Typical scenario: a product listing page with 48 items takes 2-3 seconds to load, even when the MySQL server is not overloaded. The standard CIBlockElement::GetList with property filtering generates multiple JOINs, and with 100 products having 5 properties each, EXPLAIN shows scans of hundreds of thousands of rows. TTFB exceeds 1 second even on a VPS with 4 vCPUs. The platform 1C-Bitrix is one of the popular CMS for e-commerce, yet its infoblocks often become a bottleneck. In our practice, with over 50 optimized projects, 90% of problems are solved by migrating to D7 ORM and properly placing indexes. This reduces server resource costs and stays within budget without extra investment. We guarantee a 3-5x reduction in query time. This article is the result of our years of experience.

Why Standard Bitrix Queries Are Slow?

The old API CIBlockElement::GetList when using PROPERTY_* filter adds a JOIN for each property. If there are 5 properties in the filter — 5 JOINs. The query plan becomes non-optimal, especially when the b_iblock_element_property table contains millions of rows. Additionally, the arSelect parameter with "*" or without an explicit list forces the API to pull all fields, including long texts like PREVIEW_TEXT and DETAIL_TEXT. As a result, the data volume from the database increases by 3-5 times.

Another common mistake is the N+1 query problem. After fetching a list of items, developers often call CIBlockElement::GetProperty() for each product in a loop. For 48 products, that's 1 + 48 = 49 queries. Execution time grows linearly.

How to Implement Batch Fetching Without Regression?

Switching to \Bitrix\Iblock\ElementTable from D7 ORM gives full control over SQL. Each query can be verified using getQuery()->getSql() before execution. Example of an optimal query for a catalog page:

use Bitrix\Iblock\ElementTable; $result = ElementTable::getList([ 'select' => [ 'ID', 'NAME', 'CODE', 'PREVIEW_PICTURE', 'IBLOCK_SECTION_ID', ], 'filter' => [ '=IBLOCK_ID' => CATALOG_IBLOCK_ID, '=ACTIVE' => 'Y', '=IBLOCK_SECTION_ID' => $sectionId, ], 'order' => ['SORT' => 'ASC', 'ID' => 'ASC'], 'limit' => 24, 'offset' => $page * 24, 'cache' => ['ttl' => 3600], ]); 

Explicit select without properties — the query hits only b_iblock_element, no JOINs. If property values are needed for multiple products, we use batch fetching by IDs:

$ids = array_column($elements, 'ID'); $propsResult = \CIBlockElement::GetPropertyValuesArray( $ids, CATALOG_IBLOCK_ID, ['CODE' => ['BRAND', 'COLOR', 'SIZE']] ); 

This "fetch by ID in batches" pattern solves the N+1 problem. The official documentation on D7 ORM contains all the details. 1C-Bitrix Academy

Case Study from Our Practice: Construction Materials Catalog with 45,000 SKUs

We worked with a client — an online store of construction materials. The catalog contained 45,000 active items. A section page with 48 products loaded in 1.8 seconds without cache. MySQL slow query log revealed several issues:

  • CIBlockElement::GetList with SELECT => "*" and PROPERTY_FILTER on 5 properties took 640 ms per query.
  • The "related products" block executed a separate query for each of the 6 items (N+1).
  • The section tree query had no depth level limit.

We performed the following actions:

  • Rewrote the main query to D7, leaving only 8 necessary fields.
  • Replaced iterative property queries with batch fetching using GetPropertyValuesArray.
  • Limited DEPTH_LEVEL in the section fetch and added tagged cache.
  • Created a composite index on b_iblock_element:
ALTER TABLE b_iblock_element ADD INDEX idx_iblock_section_active_sort (IBLOCK_ID, IBLOCK_SECTION_ID, ACTIVE, SORT); 

Result: TTFB of the section page without cache dropped from 1.8 s to 380 ms, with cache — to 45 ms. The number of database queries decreased from 12 to 4. MySQL load reduced by 3 times, saving the client up to 30% on server costs. The client gained the ability to serve more visitors without increasing expenses.

Comparison of Old vs. New Approach

Parameter CIBlockElement::GetList D7 ORM + Batches
JOIN count when filtering by 5 properties 5 0 (if properties not in select)
SQL control No Full (getQuery()->getSql())
N+1 risk High Eliminated by batch fetching
Caching Only file-based Tagged + data cache
Performance (example) 640 ms 80 ms

D7 API is 3-5x faster for typical queries.

What's Included in the Optimization Work

We offer comprehensive infoblock query optimization turnkey. The work includes:

  • Analysis of MySQL slow query log and Bitrix performance panel.
  • Audit of all custom components for N+1 and non-optimal fetches.
  • Rewriting critical queries to D7 ORM with explicit select and batch strategies.
  • Adding necessary composite indexes and configuring tagged cache.
  • Creating documentation for optimized queries for your team.
  • Training developers on D7 and best practices.
More about our experienceWe have been doing Bitrix development for over 10 years, certified by 1C-Bitrix. Successfully optimized catalogs for 20+ large projects with traffic from 10,000 visitors per day.

Timelines and Pricing

Stage Duration
Query audit (slow log, Explain, Bitrix panel) 1–2 days
Rework critical queries (D7, batching) 3–7 days
Indexes and cache setup 1–2 days
Documentation and training 1 day

Pricing is calculated individually based on catalog size and component count. Contact us for an evaluation of your project — it takes 2 days. Get a consultation on speeding up your catalog.