我有这个查询,它返回给定区域中的所有POI:
$query = $em
->createQuery(
'SELECT f FROM MyApplication\MyBundle\Entity\POI p
WHERE (p.latitude BETWEEN :southEastLatitude AND :norhtWestLatitude) AND
(p.longitude BETWEEN :southEastLongitude AND :norhtWestLongitude)
ORDER BY p.name
');
$query->setParameter(":norhtWestLatitude", $northWestLat);
$query->setParameter(":norhtWestLongitude", $northWestLng);
$query->setParameter(":southEastLatitude", $southEastLat);
$query->setParameter(":southEastLongitude", $southEastLng);
如果我尝试访问一个小区域(使用差异较小的参数),我成功地获得了结果。我想我的结果最多可达1000行...我不太确定。
如果我尝试访问更大的区域,我会得到一个空的结果集......
以某种方式使用更大区域的参数触发相同的查询,我得到了正确的结果集(~1060行)。
所以我想知道学说的限制(甚至是Symfony ???我在Symfony2项目中使用了学说),有没有?我也试过$query->setMaxResults(999999999);
,但没有帮助......
有人有同样的问题吗?
编辑:也许php的内存使用量很高?我在getresult之前和之后添加了这些行:
echo "Memory usage before: " . (memory_get_usage() / 1024) . " KB" . PHP_EOL;
echo "Memory usage after: " . (memory_get_usage() / 1024) . " KB" . PHP_EOL;
输出结果为:
以下内存使用情况:5964.0625 KB
以下内存使用情况:10019.421875 KB
修改 奇怪的测试:
1)如果我测试这些参数:
WHERE
(f.latitude BETWEEN 45.64273082966722 AND 47.29965978937995) AND
(f.longitude BETWEEN 4.93262593696295 AND 9.99999999999999)
我得到923行(正常行为)
2)如果我将参数9.999999999999更改为10.000000000(或某个大于9.9999999的数字),我的应用程序中的结果集为空。 数据库仍然返回923行(对于10.000000000)。
修改 我可以解决这个问题,在这里讨论:https://groups.google.com/d/msg/doctrine-user/qLSon6m4nM4/y5vLztHcbDgJ
答案 0 :(得分:2)
从Doctrine2邮件列表中我了解到您将属性映射为“string”类型:
/** @ORM\Column(name="latitude", type="string", length=255, nullable=false) */
private $latitude;
/** @ORM\Column(name="longitude", type="string", length=255, nullable=false) */
private $longitude;
这意味着您的数据库将具有这些属性的VARCHAR列。因此,当db运行您的查询时,它将执行字符串比较。
字符串比较与(正常)数字比较不同。看到这些结果:
$a = 1234567890;
$b = 987654321;
echo $a == $b ? '0' : ($a < $b ? '-1' : '1'); // output: 1 (means $a is bigger than $b)
echo strcmp( $a, $b ); // output: -8 (means $a is smaller than $b)
因此,最好将属性映射为表示数据库中数字的内容(DECIMAL将是一个不错的选择):
/** @ORM\Column(name="latitude", type="decimal", nullable=false) */
private $latitude;
/** @ORM\Column(name="longitude", type="decimal", nullable=false) */
private $longitude;
PS:您提到自己执行查询时获得了有效的结果。这可能是因为你做了:
... latitude BETWEEN 45.64273082966722 AND 47.29965978937995 ...
但是Doctrine(因为你将属性映射为字符串)将会:
... latitude BETWEEN '45.64273082966722' AND '47.29965978937995' ...
请注意这里的引用。如何处理这两个语句有很大的不同,比如我的测试用例显示;)
答案 1 :(得分:1)
这可能与内存使用有关。请查看您的apache日志以查找内存错误。
选择大量数据时,使用$query->iterate()
代替$query->getResult()
,as pointed out in this article可能会有所帮助。
要检查您的查询是否生成了正确的SQL,您可以记录或以其他方式输出调用$query->getSQL()
的结果(在设置参数之后)。将生成的SQL提供给您选择的数据库客户端,以查看是否返回了所需的结果。