Views: 7730
Last Modified: 12.09.2014

The Use of the GetList Method

Quite often many developers use the query CIBlockElement::GetById in their projects. It is a simple and convenient method for when a value of fields of an infoblock element is needed. But this method returns all fields and all properties of an element. In case of an infoblock with a big amount of properties and intense traffic on a website this simple query will result in performance reduction. And if there are several dozens of such queries in various result_modifier of different components, it turns out that, in aggregate, despite of caching, such selections create peak loads at the time of cache update.

If a value of a specific field or fields (and not all fields and properties) is needed, it is better to use GetList indicating the specific field of an element.

Note: GetByID invokes GetList inside. The difference is that GetByID in any case returns all the fields and properties, and in GetList the list of returned fields can be limited with a filter.

Also, the GetList methods permit you to select several entries at once, while GetByID permits to select just one entry.

The sole advantage of GetById over GetList from the developer’s point of view is that GetById can be just called. Direct use of GetList requires certain work with code (creation of an array of parameters).

Important Examples of Performance Enhancement

Important! Multiple same-type queries create a big load. The amount of queries should be reduced whenever possible.

  1. Let us consider an example when for some elements of one infoblock (books’ authors) additional properties from another infoblock (information about authors) must be obtained, for example, by changing the template or result modifier.

    In the majority of cases, it is made in a cycle, for example:

     // incorrect sampling option, an additional query is made for each element
    foreach($arResult['ITEMS'] as $ikey => ival)
    {
        $avtorID = intval($ival['PROPERTIES']['AVTOR']['VALUE']);
        if($avtorID > 0)
        {
            $rs = CIBlockElement::GetByID($avtorID);
            while($ar = $rs->GetNext())
            {
                $arResulr['ITEMS'][$ikey]['AVTOR_INFO'][] = $ar;
            }
        }
    }
    

    Such cycle creates multiple queries and it reduces performance.

    The correct option is to use one query to receive data for the elements needed:

    // correct option, information on authors is selected in one query, and only required information is included
    $avtorID = array();
    
    foreach($arResult['ITEMS'] as $ikey => ival)
    {
        $aID = intval($ival['PROPERTIES']['AVTOR']['VALUE']);
        if($aID > 0)
        {
            $avtorID[] = $aID;
        }
    }
    
    $avtorID = array_unique($avtorID);
    
    
    $rs = CIBlockElement::GetList(
        array('ID' => 'ASC'),
        array(
            'IBLOCK_ID' => XX,
            'ID' => $avtorID,
            'ACTIVE' => 'Y'
        ),
        false,
        false,
        array('ID', 'NAME', 'PREVIEW_PICTURE')
    
    );
    while($ar = $rs->GetNext())
    {
        $arResulr['AVTOR_INFO'][$ar['ID']] = $ar;
    }
    

  2. If we can change the main API query, for example, using own component, the data on authors from the examples shown above can be obtained at once:
    // correct option,
    // information on books and related information on authors is selected in one query
    $rs = CIBlockElement::GetList(
        array('ID' => 'ASC'),
        array(
            'IBLOCK_ID' => YY,
            'ACTIVE' => 'Y'
        ),
        false,
        false,
        array(
            'ID',
            'NAME',
            'PREVIEW_PICTURE',
            'PREVIEW_TEXT',
            'PROPERTY_AVTOR.NAME',
            'PROPERTY_AVTOR.PREVIEW_PICTURE',
        )
    
    );
    while($ar = $rs->GetNext())
    {
        $arResulr['ITEMS'][] = $ar;
    }
    

  3. Use of a more appropriate code which reduces the amount of queries.

    Example: It is necessary to check for a list of specific users regarding whether or not they are in a given group.

    Standard code:

    foreach ($arSomeUser as $arUser)
    {
        $arGroups = CUser::GetUserGroup($arUser['ID']);
        if(in_array(5, $arGroups))
        {
            // code
        }
    }
    

    In this case, the amount of queries will be equal to the amount of users on the list + one for selection of required users from among all possible users (the very first query).

    If there are not many users in the group, the following approach will be more appropriate:

    $rsUser = $arUser->GetList(($by="ID"), ($order="desc"), array('ACTIVE' => 'Y', 'GROUPS_ID' => 5 ....))
    while($arUser = $rsUser->GetNext())
    {
            // code
    }
    


Courses developed by Bitrix24