0

在我们的应用程序中,我们使用这 3 个表:

  1. 类别
  2. 城市(category_id)
  3. city_data(距离,city_id)
$q = "SELECT a.id as aid,a.distance as adistance, 
           b.id as bid,b.distance as bdistance 
        FROM city_data as a 
        JOIN city_data as b on a.id != b.id 
        JOIN cities AS a_cities ON a.city_id = a_cities.id
        JOIN cities AS b_cities ON b.city_id = b_cities.id      
        WHERE (a_cities.category_id='".$_GET["c"]."' AND b_cities.category_id='".$_GET["c"]."')
        AND abs(a.distance - b.distance) < 100 ORDER BY RAND() LIMIT 1";

城市city_data具有相同的行数 -几乎 5.000。上面的查询大约需要45 秒,这很糟糕。更糟糕的是,这些表应该有另外 5.000 行,总共有 10.000 行......

我想问你任何方式,如何减少执行上述查询的时间...... 45s是不可接受的......

我有什么办法可以解决这个问题吗?

编辑:谢谢你的建议,我删除了 ORDER BY RAND()部分,时间真的很短,大约 22 秒,但这对于通常使用来说仍然太高了

4

5 回答 5

2

确保您已在连接列上创建索引(cities.city_id、city_data.id、citys.category_id)

于 2012-09-06T23:31:25.650 回答
2

我不知道您的表是如何设计的,但您应该将 city1 到 city2 的距离信息保存在一个(可能是另一个)表中,并摆脱最后 2 个连接并获取另一个查询结果的类别信息。

如之前给出的示例(计算 400 个城市之间的距离并为其优化 MySQL?

SELECT c1.name, c2.name, cd.dist 
FROM cities_dist cd
  INNER JOIN cities c1 ON cd.city1 = c1.id
  INNER JOIN cities c2 ON cd.city2 = c2.id
WHERE cd.city1 = your_id
   OR cd.city2 = your_id
ORDER BY cd.dist ASC

并确保您有正确的索引和字段类型定义。

于 2012-09-07T00:20:44.703 回答
1

你为什么要加入这个?

FROM city_data as a JOIN city_data as b on a.id != b.id 

您正在将city_data表的数据与同一个表的数据连接起来,其中您不匹配它们之间的唯一关系。我想这就是让您的查询如此缓慢的原因。

于 2012-09-06T23:18:17.210 回答
0

分解查询。将每个子查询变成一个视图。分别运行它们。这应该可以让您提高性能。运行一个很长的非常复杂的查询通常比运行一个简化的查询要慢。尽可能限制每个子查询的结果。那么也许你可以使用联合来加入结果。那将是我的第一种方法。

于 2012-09-06T23:48:23.737 回答
0

将所有这些数据拉回 PHP 并在那里进行循环/距离计算可能是有意义的——这在代码中可能比在数据库中更快。

于 2012-09-07T00:16:03.440 回答