Closed
Description
Summary (*)
When you use multiple extension attributes from the same table, left join
will be generated for each case.
Issue has been faced during 'In Store Pickup' feature implementation in PR: magento/inventory#2125.
Examples (*)
- Create simple table via
db_schema.xml
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="custom_table" engine="innodb">
<column xsi:type="int" name="order_id" padding="10" unsigned="true" nullable="false"/>
<column xsi:type="varchar" name="custom_col1" nullable="false" default="custom_value1"/>
<column xsi:type="varchar" name="custom_col2" nullable="false" default="custom_value2"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="order_id"/>
</constraint>
<constraint xsi:type="foreign" referenceId="CUSTOM_TABLE_ORDER_ID_SALES_ORDER_ENTITY_ID"
table="custom_table" column="order_id" referenceTable="sales_order"
referenceColumn="entity_id" onDelete="CASCADE"/>
</table>
</schema>
And db_schema_whitelist.json
{
"custom_table": {
"column": {
"order_id": true,
"custom_col1": true,
"custom_col2": true
},
"constraint": {
"PRIMARY": true,
"CUSTOM_TABLE_ORDER_ID_SALES_ORDER_ENTITY_ID": true
}
}
}
- Create extension attribute in
extension_attributes.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Sales\Api\Data\OrderInterface">
<attribute code="custom_col1" type="string">
<join reference_table="custom_table" join_on_field="entity_id" reference_field="order_id">
<field column="custom_col1">custom_col1</field>
</join>
</attribute>
<attribute code="custom_col2" type="string">
<join reference_table="custom_table" join_on_field="entity_id" reference_field="order_id">
<field column="custom_col2">custom_col1</field>
</join>
</attribute>
</extension_attributes>
</config>
- Apply fix for
OrderRepository
(see magento/magento2#8035: Join extension attributes are not added to Order results (REST api) #21797) - Check SQL query for loaded collection via (\Magento\Sales\Model\OrderRepository::getList)
public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
{
/** @var \Magento\Sales\Api\Data\OrderSearchResultInterface $searchResult */
$searchResult = $this->searchResultFactory->create();
/** @var \Magento\Framework\Api\ExtensionAttribute\JoinProcessor $extensionJoinProcessor */
$extensionJoinProcessor = ObjectManager::getInstance()->get('\Magento\Framework\Api\ExtensionAttribute\JoinProcessor');
$extensionJoinProcessor->process($searchResult);
$this->collectionProcessor->process($searchCriteria, $searchResult);
$searchResult->setSearchCriteria($searchCriteria);
echo (string)$searchResult->getSelect();
die;
foreach ($searchResult->getItems() as $order) {
$this->setShippingAssignments($order);
$this->setOrderTaxDetails($order);
$this->setPaymentAdditionalInfo($order);
}
return $searchResult;
}
- You will see two
left joins
of the same table with the same conditions instead of single one. This will cause performance degradation with every added extension attribute.
Proposed solution
Create table aliases base on table name to be joined and join conditions in
\Magento\Framework\Api\ExtensionAttribute\JoinProcessorHelper::getReferenceTableAlias