Я просмотрел связанные с этим вопросы на этом сайте, но никто из них не ответил на мой вопрос. У меня есть следующие инструкции в веб-сайт с помощью Propel:Propel ORM - запросы UNION
$query = $query
->distinct()
->select(Request::getTransferFieldsWithRelations())
->leftJoinResponse("Response")
->joinWith("Request.SupportStatus SupportStatus")
->joinWith("Request.CustomerGroup CustomerGroup", Criteria::LEFT_JOIN)
->joinWith("Request.Customer Customer", Criteria::LEFT_JOIN)
->joinWith("Request.Site Site", Criteria::LEFT_JOIN)
->joinWith("Request.InternalUser InternalUser", Criteria::LEFT_JOIN)
->joinWith("Request.User User", Criteria::LEFT_JOIN)
->orderBy("CreatedDate", Criteria::ASC);
$conditions = array(
"and" => array(),
"or" => array()
);
if(isset($args["QueryText"]) && $args["QueryText"] != "") {
$query = $query
->withColumn("(MATCH (Request.Subject, Request.Detail) AGAINST ('" . $args["QueryText"] . "' IN BOOLEAN MODE) + MATCH (Response.Response) AGAINST ('" . $args["QueryText"] . "' IN BOOLEAN MODE))", "RequestRelevance")
->condition('cond1', "(MATCH (Request.Subject, Request.Detail) AGAINST ('" . $args["QueryText"] . "' IN BOOLEAN MODE) + MATCH (Response.Response) AGAINST ('" . $args["QueryText"] . "' IN BOOLEAN MODE)) > 0.2")
->condition('cond2', 'Request.Id = ?', $args["QueryText"])
->where(array('cond1', 'cond2'), 'or')
->orderBy("RequestRelevance", Criteria::DESC);
}
if(isset($args["OpenCallsOnly"]) && $args["OpenCallsOnly"] == 1) {
$query = $query
->useSupportStatusQuery()
->filterByOutstanding(1)
->endUse();
}
if(isset($args["ClosedCallsOnly"]) && $args["ClosedCallsOnly"] == 1) {
$query = $query
->useSupportStatusQuery()
->filterByIsClosed(1)
->endUse();
}
...
foreach ($conditions as $key => $value) {
if(!empty($value)){
$query = $query
->where($value, $key);
}
}
Однако этот запрос занимает хорошие 20 секунд, чтобы выполнить на веб-сайте, если сортировать по ClosedCallsOnly
(так почти 50000 результатов) и в течение 8 секунд при использовании сырой SQL , Я оптимизировал его следующий запрос, используя UNION
заявления:
(SELECT DISTINCT
requests.requestID AS "Id", requests.subject AS "Subject", requests.detail AS "Detail", requests.created AS "CreatedDate", requests.lastresponsedate AS "LastResponseDate", SupportStatus.supportstatusID AS "SupportStatus.Id", SupportStatus.supportstatus AS "SupportStatus.Name", SupportStatus.isnew AS "SupportStatus.IsNew", SupportStatus.isclosed AS "SupportStatus.IsClosed", CustomerGroup.customergroupID AS "CustomerGroup.Id", CustomerGroup.customergroup AS "CustomerGroup.Name", Site.siteID AS "Site.Id", Site.site AS "Site.Name", InternalUser.userID AS "InternalUser.Id", InternalUser.username AS "InternalUser.Username", User.userID AS "User.Id", User.username AS "User.Username", Customer.customerID AS "Customer.Id", Customer.customer AS "Customer.Name", Customer.customergroupID AS "Customer.CustomerGroupId", Customer.rate AS "Customer.Rate"
FROM requests
LEFT JOIN responses Response ON (requests.requestID=Response.requestID)
INNER JOIN supportstatus SupportStatus ON (requests.supportstatusID=SupportStatus.supportstatusID)
INNER JOIN customergroups CustomerGroup ON (requests.customergroupID=CustomerGroup.customergroupID)
INNER JOIN customers Customer ON (requests.customerID=Customer.customerID)
INNER JOIN sites Site ON (requests.siteID=Site.siteID)
LEFT JOIN users InternalUser ON (requests.internal_userID=InternalUser.userID)
LEFT JOIN users User ON (requests.userID=User.userID)
WHERE ((MATCH (requests.subject, requests.detail) AGAINST ('slow pc' IN BOOLEAN MODE)
))
ORDER BY requests.created ASC)
UNION
(SELECT DISTINCT
requests.requestID AS "Id", requests.subject AS "Subject", requests.detail AS "Detail", requests.created AS "CreatedDate", requests.lastresponsedate AS "LastResponseDate", SupportStatus.supportstatusID AS "SupportStatus.Id", SupportStatus.supportstatus AS "SupportStatus.Name", SupportStatus.isnew AS "SupportStatus.IsNew", SupportStatus.isclosed AS "SupportStatus.IsClosed", CustomerGroup.customergroupID AS "CustomerGroup.Id", CustomerGroup.customergroup AS "CustomerGroup.Name", Site.siteID AS "Site.Id", Site.site AS "Site.Name", InternalUser.userID AS "InternalUser.Id", InternalUser.username AS "InternalUser.Username", User.userID AS "User.Id", User.username AS "User.Username", Customer.customerID AS "Customer.Id", Customer.customer AS "Customer.Name", Customer.customergroupID AS "Customer.CustomerGroupId", Customer.rate AS "Customer.Rate"
FROM requests
LEFT JOIN responses Response ON (requests.requestID=Response.requestID)
INNER JOIN supportstatus SupportStatus ON (requests.supportstatusID=SupportStatus.supportstatusID)
INNER JOIN customergroups CustomerGroup ON (requests.customergroupID=CustomerGroup.customergroupID)
INNER JOIN customers Customer ON (requests.customerID=Customer.customerID)
INNER JOIN sites Site ON (requests.siteID=Site.siteID)
LEFT JOIN users InternalUser ON (requests.internal_userID=InternalUser.userID)
LEFT JOIN users User ON (requests.userID=User.userID)
WHERE (requests.requestID = 'slow pc')
ORDER BY requests.created ASC)
UNION
(SELECT DISTINCT
Request.requestID AS "Id", Request.subject AS "Subject", Request.detail AS "Detail", Request.created AS "CreatedDate", Request.lastresponsedate AS "LastResponseDate", SupportStatus.supportstatusID AS "SupportStatus.Id", SupportStatus.supportstatus AS "SupportStatus.Name", SupportStatus.isnew AS "SupportStatus.IsNew", SupportStatus.isclosed AS "SupportStatus.IsClosed", CustomerGroup.customergroupID AS "CustomerGroup.Id", CustomerGroup.customergroup AS "CustomerGroup.Name", Site.siteID AS "Site.Id", Site.site AS "Site.Name", InternalUser.userID AS "InternalUser.Id", InternalUser.username AS "InternalUser.Username", User.userID AS "User.Id", User.username AS "User.Username", Customer.customerID AS "Customer.Id", Customer.customer AS "Customer.Name", Customer.customergroupID AS "Customer.CustomerGroupId", Customer.rate AS "Customer.Rate"
FROM responses
LEFT JOIN requests Request ON (Request.requestID=responses.requestID)
INNER JOIN supportstatus SupportStatus ON (Request.supportstatusID=SupportStatus.supportstatusID)
INNER JOIN customergroups CustomerGroup ON (Request.customergroupID=CustomerGroup.customergroupID)
INNER JOIN customers Customer ON (Request.customerID=Customer.customerID)
INNER JOIN sites Site ON (Request.siteID=Site.siteID)
LEFT JOIN users InternalUser ON (Request.internal_userID=InternalUser.userID)
LEFT JOIN users User ON (Request.userID=User.userID)
WHERE ((
MATCH (responses.response) AGAINST ('slow pc' IN BOOLEAN MODE)))
ORDER BY Request.created ASC)
времени выполнения этого оператора улучшает примерно 8й, который очень хорошо, но, к сожалению, я не знаю, как перевести его на запрос Propel. Если посмотреть на другие вопросы, кажется, что использование UNION
в Propel невозможно. Я знаю, что использование операторов SQL возможно в Propel, но поскольку запросы Propel используются везде в этом классе, я не уверен, как это возможно? Как я могу реализовать этот запрос на своем веб-сайте? При необходимости я могу предоставить больше кода для этого класса.
Иногда вам просто нужно писать исходный SQL, особенно при оптимизации таких больших запросов. – Shelvacu