【问题标题】:Apply PHP compare function to all elements in MySQL table将 PHP 比较函数应用于 MySQL 表中的所有元素
【发布时间】:2014-08-19 20:38:11
【问题描述】:

我正在构建一个算法,该算法采用欧几里得坐标(例如 (-4, 2))并在包含其他坐标的大型数据库表中搜索以找到最近的坐标(使用欧几里得距离公式)。目前,我的代码如下所示:

$x = -4;
$y = 2;
$query = mysql_query('SELECT `x`, `y` FROM `myTable`');
$closest = PHP_INT_MAX;
while($row=mysql_fetch_array($query)){
    $dist = distFormula($x, $y, $row[x], $row[y]);
    if($dist<$closest)
        $closest = $dist;
}
echo $closest;

distFormula($x1, $y1, $x2, $y2){
    return sqrt(pow($x2-$x1, 2)+pow($y2-$y1, 2));
}

有没有更有效的方法来做到这一点?我的数据库表可能非常大。有没有办法在查询中进行比较?此外,出于示例的目的,我在本例中使用了二维,但实际上我打算使用大量维度(更长的坐标)。

感谢您的帮助!

【问题讨论】:

  • 你可以在db端进行计算,但还是要全表扫描...

标签: php mysql performance algorithm euclidean-distance


【解决方案1】:

是的,您可以在查询中在 MySQL 中进行此类计算。试试这个:

$query = <<<SQL
  SELECT * FROM (SELECT $x originX, $y originY, x closestX, y closestY, SQRT(
       ($x-x)*($x-x)
     + ($y-y)*($y-y)
  ) dist FROM `myTable`) a ORDER BY dist DESC LIMIT 1
SQL;

确保最后一行是单独的,开头或结尾没有其他字符。

它应该给出结果中“dist”列内的距离

这是一个 3 维的示例...

$query = <<<SQL
  SELECT * FROM (
      SELECT 
         $x originX, $y originY, $z originZ, 
         x closestX, y closestY, z closestZ 
         SQRT(
           ($x-x)*($x-x)
         + ($y-y)*($y-y)
         + ($z-z)*($z-z)
  ) dist FROM `myTable`) a ORDER BY dist DESC LIMIT 1
SQL;

【讨论】:

  • 不是这样的比较,而是这样的计算——在你的例子中
  • 他需要最短距离,所以那里应该有MIN
  • 非常感谢您的回复! :) 三个问题:首先,因为必须检查每一行,所以充其量总是 O(n) 时间,对吧?其次,在 MySQL 中这样做真的比在 PHP 中更快吗?最后,给定一些$n,如何调整它以实现 n 维欧几里得距离公式,就像我在帖子末尾提到的那样? MySQL 中需要一个循环,对吗?见:en.wikipedia.org/wiki/Euclidean_distance
  • 好点@BartFriederichs,但最后是正确的。我已经使示例更加健壮,因此它只返回最接近的结果,并给出原点 X/Y 和最接近的 X/Y(如果需要,您还可以获取该结果行的 ID...)
  • 是的,没错。例如,如果您需要查看需要与之前比较的维度,只需提前触发快速 SQL 查询以获取列名或其他内容
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-24
  • 2017-03-09
  • 2019-04-20
  • 2020-02-04
  • 2016-05-02
  • 1970-01-01
  • 2021-12-29
相关资源
最近更新 更多