我是初学者,我在想的Joomla更新表(3.8)数据库中,我得到504网关超时在下面的SQL查询nginx的错误:
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$condition = array(
$db->quoteName('B.virtuemart_product_id') . ' >= '.$product_id_from,
$db->quoteName('B.virtuemart_product_id') . ' <= '.$product_id_to);
$query->select(array('B.virtuemart_product_id, A.product_sku,
A.price_CZK, A.price_EUR'))
->from($db->quoteName('#__watrex_price_list_temp', 'A'))
->join('INNER' , $db->quoteName('#__virtuemart_products', 'B') . '
ON (' . $db->quoteName('B.product_sku') . ' = ' . $db-
>quoteName('A.product_sku') . ')')
->where($condition,'AND');
$db->setQuery($query);
$num_rows = $db->getNumRows();
$results = $db->loadObjectList();
...
结果最多可以包含50000个项目。我该如何解决这个问题?谢谢
答案 0 :(得分:1)
我怀疑getNumRows()是这里的罪魁祸首。当我在本地主机上运行调用echo $db->getNumRows()
并成功查询返回非空结果集以复制问题时,我得到:
警告:mysqli_num_rows()期望参数1为mysqli_result,在###
行上的C:\ wamp64 \ www \ blah \ libraries \ joomla \ database \ driver \ mysqli.php中给出空值。 > NULL
要解决此问题,请在$db->execute();
之前的行中添加$db->getNumRows()
,一切都会愉快并按需进行。也就是说,我建议您仅在count()
上调用sizeof()
或$results
,因为您将获得相同的输出,而不必添加execute()
调用。
如果不是原因,则可能会或可能不在您的控制范围内。您不妨查看以下建议清单:https://www.lifewire.com/504-gateway-timeout-error-explained-2622941
关于如何以较少的内存消耗来处理结果集,您可以娱乐James Garrett's suggestion。
对于查询的细微改进:
您的SELECT子句可以正确呈现,但语法的设计似乎旨在创建一个列数组。事实是,您有一个包含所有四列的单元素数组。仅当您决定将quoteName()
应用于数组时,这才成为问题。
我建议使用小写的表别名,以免它们成为MySQL关键字。 SQL Queries - Paragraph 1
ON
声明不需要用括号括起来。
实际上没有任何表或列需要调用quoteName()
来保持稳定性/安全性。您可以选择省略它们,以使您的代码更易于阅读,但是Joomla编码标准要求100%使用此电话(我个人不喜欢这种立场)。 SQL Queries - Paragraph 5
表名和表列名应始终包含在quoteName()方法中,以转义表名和表列。
它可能对性能没有帮助,但是BETWEEN是“包容性的”,并且经过专门设计可以满足您在两个WHERE条件下的要求。 https://www.techonthenet.com/mysql/between.php
我推荐的代码段:
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName(["b.virtuemart_product_id", "a.product_sku", "a.price_CZK", "a.price_EUR"]))
->from($db->quoteName("#__watrex_price_list_temp", "a"))
->innerJoin($db->quoteName("#__virtuemart_products", "b") . " ON " . $db->quoteName('b.product_sku') . " = " . $db>quoteName("a.product_sku"))
->where($db->quoteName("b.virtuemart_product_id") . " BETWEEN " . (int)$product_id_from . " AND " . (int)$product_id_to);
$db->setQuery($query);
if (!$results = $db->loadObjectList()) {
echo "No Rows";
} else {
// if you need to know the count...
echo count($results);
// iterate the result set
foreach ($results as $row) {
// ... yatta-yatta ...
}
}
如果以上所有步骤均失败,建议您重新考虑您的项目。也许您应该使用LIMIT减少结果集的体积,并在必要时使用分页技术。
p.s。瑞克·詹姆斯(Rick James)有some excellent advice about adding indexes。