Skip to content

Commit 43d521d

Browse files
author
Oleksandr Iegorov
committed
MAGETWO-96242: High Database Load for Sales Rule Validation
1 parent 2edfe60 commit 43d521d

File tree

1 file changed

+73
-54
lines changed

1 file changed

+73
-54
lines changed

app/code/Magento/SalesRule/Model/ResourceModel/Rule/Collection.php

Lines changed: 73 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -162,67 +162,17 @@ public function setValidationFilter(
162162

163163
$connection = $this->getConnection();
164164
if (strlen($couponCode)) {
165-
$select->joinLeft(
166-
['rule_coupons' => $this->getTable('salesrule_coupon')],
167-
$connection->quoteInto(
168-
'main_table.rule_id = rule_coupons.rule_id AND main_table.coupon_type != ?',
169-
\Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON
170-
),
171-
['code']
172-
);
173-
174165
$noCouponWhereCondition = $connection->quoteInto(
175-
'main_table.coupon_type = ? ',
166+
'main_table.coupon_type = ?',
176167
\Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON
177168
);
178-
179-
$autoGeneratedCouponCondition = [
180-
$connection->quoteInto(
181-
"main_table.coupon_type = ?",
182-
\Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO
183-
),
184-
$connection->quoteInto(
185-
"rule_coupons.type = ?",
186-
\Magento\SalesRule\Api\Data\CouponInterface::TYPE_GENERATED
187-
),
188-
];
189-
190-
$orWhereConditions = [
191-
"(" . implode($autoGeneratedCouponCondition, " AND ") . ")",
192-
$connection->quoteInto(
193-
'(main_table.coupon_type = ? AND main_table.use_auto_generation = 1 AND rule_coupons.type = 1)',
194-
\Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC
195-
),
196-
$connection->quoteInto(
197-
'(main_table.coupon_type = ? AND main_table.use_auto_generation = 0 AND rule_coupons.type = 0)',
198-
\Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC
199-
),
200-
];
201-
202-
$andWhereConditions = [
203-
$connection->quoteInto(
204-
'rule_coupons.code = ?',
205-
$couponCode
206-
),
207-
$connection->quoteInto(
208-
'(rule_coupons.expiration_date IS NULL OR rule_coupons.expiration_date >= ?)',
209-
$this->_date->date()->format('Y-m-d')
210-
),
211-
];
212-
213-
$orWhereCondition = implode(' OR ', $orWhereConditions);
214-
$andWhereCondition = implode(' AND ', $andWhereConditions);
215-
216-
$selectClone = clone $select;
169+
$relatedRulesIds = $this->getCouponRelatedRuleIds($couponCode);
217170

218171
$select->where(
219-
'(' . $orWhereCondition . ') AND ' . $andWhereCondition,
220-
null,
172+
$noCouponWhereCondition . ' OR main_table.rule_id IN (?)',
173+
$relatedRulesIds,
221174
Select::TYPE_CONDITION
222175
);
223-
$selectClone->where($noCouponWhereCondition, null, Select::TYPE_CONDITION);
224-
$select = $this->getConnection()->select()->union([$select, $selectClone]);
225-
$this->_select = $select;
226176
} else {
227177
$this->addFieldToFilter(
228178
'main_table.coupon_type',
@@ -236,6 +186,75 @@ public function setValidationFilter(
236186
return $this;
237187
}
238188

189+
/**
190+
* Get rules ids related to coupon code
191+
*
192+
* @param string $couponCode
193+
* @return array|null
194+
*/
195+
private function getCouponRelatedRuleIds(string $couponCode): ?array
196+
{
197+
$connection = $this->getConnection();
198+
$select = $connection->select()->from(
199+
['main_table' => $this->getTable('salesrule')],
200+
'rule_id'
201+
);
202+
$select->joinLeft(
203+
['rule_coupons' => $this->getTable('salesrule_coupon')],
204+
$connection->quoteInto(
205+
'main_table.rule_id = rule_coupons.rule_id AND main_table.coupon_type != ?',
206+
\Magento\SalesRule\Model\Rule::COUPON_TYPE_NO_COUPON,
207+
null
208+
)
209+
);
210+
211+
$autoGeneratedCouponCondition = [
212+
$connection->quoteInto(
213+
"main_table.coupon_type = ?",
214+
\Magento\SalesRule\Model\Rule::COUPON_TYPE_AUTO
215+
),
216+
$connection->quoteInto(
217+
"rule_coupons.type = ?",
218+
\Magento\SalesRule\Api\Data\CouponInterface::TYPE_GENERATED
219+
),
220+
];
221+
222+
$orWhereConditions = [
223+
"(" . implode($autoGeneratedCouponCondition, " AND ") . ")",
224+
$connection->quoteInto(
225+
'(main_table.coupon_type = ? AND main_table.use_auto_generation = 1 AND rule_coupons.type = 1)',
226+
\Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC
227+
),
228+
$connection->quoteInto(
229+
'(main_table.coupon_type = ? AND main_table.use_auto_generation = 0 AND rule_coupons.type = 0)',
230+
\Magento\SalesRule\Model\Rule::COUPON_TYPE_SPECIFIC
231+
),
232+
];
233+
234+
$andWhereConditions = [
235+
$connection->quoteInto(
236+
'rule_coupons.code = ?',
237+
$couponCode
238+
),
239+
$connection->quoteInto(
240+
'(rule_coupons.expiration_date IS NULL OR rule_coupons.expiration_date >= ?)',
241+
$this->_date->date()->format('Y-m-d')
242+
),
243+
];
244+
245+
$orWhereCondition = implode(' OR ', $orWhereConditions);
246+
$andWhereCondition = implode(' AND ', $andWhereConditions);
247+
248+
$select->where(
249+
'(' . $orWhereCondition . ') AND ' . $andWhereCondition,
250+
null,
251+
Select::TYPE_CONDITION
252+
);
253+
$select->group('main_table.rule_id');
254+
255+
return $connection->fetchCol($select);
256+
}
257+
239258
/**
240259
* Filter collection by website(s), customer group(s) and date.
241260
* Filter collection to only active rules.

0 commit comments

Comments
 (0)