PHP,SQL - 复杂的查询需要40多秒

时间:2012-09-06 23:12:11

标签: php mysql sql join

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

  1. 类别
  2. cities(category_id)
  3. city_data(distance,city_id)
  4. $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秒,但这仍然太高了通常使用

5 个答案:

答案 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中更快。