J'ai regardé des questions connexes à ce sujet sur le site mais aucun d'entre eux ne répond vraiment à ma question. Je les déclarations suivantes dans un site Web en utilisant Propel:Propel ORM - UNION requêtes
$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);
}
}
Cependant, cette requête prend un bon 20 secondes pour exécuter sur le site si le tri par ClosedCallsOnly
(donc près de 50 000 résultats) et plus de 8 secondes si vous utilisez SQL brut . Je l'ai optimisé à la requête suivante, en utilisant UNION
déclarations:
(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)
temps d'exécution de cette instruction améliore à peu près 8x qui est vraiment bon, mais malheureusement, je ne suis pas sûr de savoir comment traduire à une requête Propel. En regardant d'autres questions, il semble que l'utilisation de UNION
dans Propel n'est pas possible. Je sais que l'utilisation d'instructions SQL est possible dans Propel mais comme les requêtes Propel sont utilisées partout ailleurs dans cette classe, je ne suis pas sûr de savoir comment cela serait possible? Comment pourrais-je implémenter cette requête sur mon site? Si nécessaire, je peux fournir plus de code pour cette classe.
Parfois, il suffit d'écrire du SQL brut, en particulier lors de l'optimisation de requêtes de ce type. – Shelvacu