在我们的应用中,我们使用这3个表:
$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秒,但这仍然太高了通常使用
答案 0 :(得分:2)
确保您已在已加入的列上创建索引(cities.city_id,city_data.id,cities.category_id)
答案 1 :(得分:2)
我不知道您的表是如何设计的,但您应该将city1与city2距离信息保存在一个(可能是另一个)表中,并删除最后2个连接,并在另一个查询中获取结果的类别信息。
与先前给出的样本(Calculating distance between 400 cities and optimizing MySQL for it?)
一样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
确保您拥有正确的索引和字段类型定义。
答案 2 :(得分:1)
你为什么要加入这个?
FROM city_data as a JOIN city_data as b on a.id != b.id
您正在使用同一个表中的数据加入city_data
表的数据,在这些表中您不匹配它们之间的唯一关系。我想这就是让你的查询变得如此缓慢的原因。
答案 3 :(得分:0)
打破查询。将每个子查询转换为视图。单独运行它们。这应该可以让你提高性能。运行一个非常复杂的查询通常比运行简化查询慢。还要尽可能限制每个子查询的结果。那么也许你可以使用工会来加入结果。那将是我的第一个方法。
答案 4 :(得分:0)
将所有这些数据提取回PHP并在那里进行循环/距离计算可能是有意义的 - 这可能在代码中比在DB中更快。