Php 帮助解决SQL查询速度和性能问题

Php 帮助解决SQL查询速度和性能问题,php,sql,performance,logic,pseudocode,Php,Sql,Performance,Logic,Pseudocode,我有一个汽车分类列表网站,我正在开发内置PHP。用户使用主页上的下拉选项框输入他们想要的汽车的详细信息。当他们点击提交时,他们会进入结果页面,这就是我遇到的问题 目前的设置方式是: 在数据库中查询与他们要查找的汽车匹配的任何结果。查询返回汽车的ID和广告的邮政编码 然后检查每个广告的用户邮政编码和广告邮政编码之间的距离。这本身就需要一个数据库查询来查找每个广告的各个邮政编码的坐标,对于每次超过350个结果来说,这是相当耗时的 然后使用if语句确定距离是否小于或等于用户在主页上输入的距离 如果广告

我有一个汽车分类列表网站,我正在开发内置PHP。用户使用主页上的下拉选项框输入他们想要的汽车的详细信息。当他们点击提交时,他们会进入结果页面,这就是我遇到的问题

目前的设置方式是:

  • 在数据库中查询与他们要查找的汽车匹配的任何结果。查询返回汽车的ID和广告的邮政编码
  • 然后检查每个广告的用户邮政编码和广告邮政编码之间的距离。这本身就需要一个数据库查询来查找每个广告的各个邮政编码的坐标,对于每次超过350个结果来说,这是相当耗时的
  • 然后使用if语句确定距离是否小于或等于用户在主页上输入的距离
  • 如果广告在允许的距离内,则将其ID添加到数组中
  • 然后计算阵列中的广告总数,并使用该总数来确定取决于广告数量和页面上要显示的广告数量的变量
  • 然后使用
    WHERE
    语句和数组中的ID执行广告表的第二个查询。e、 g.
    从ID=1、ID=4、ID=23的广告中选择*。。。。。。。。查询中使用的ID总数取决于第5点中提到的变量。然后,当用户单击“下一页”时,将从保留查询的数组中的位置重新运行该查询,然后重新创建并执行该查询
  • 我面临的问题是,完成这项工作需要很长时间,我一直在寻找一种更节省资源和时间的方式来完成它

    它最初的设计是使用WHERE子句执行一个查询,以满足每个用户对汽车的特定需求,然后在输出到页面之前,使用if语句检查距离。这导致页面编号出现问题,因为无法确定与查询中返回的广告的距离要求相匹配的广告数量-因此,在收集完整广告之前,通过满足距离条件的方式来确定要显示的广告的确切数量算计的

    抱歉,这有点长-希望它有意义。我没有包含任何代码,因为这会使它变长,而且与实际代码相反,这是一个逻辑问题

    谢谢你的建议

    有人请求了表布局和SQL。这是

    广告台

    ID、品牌、型号、颜色、里程、发动机、年份、邮政编码

    邮政编码表

    ID,邮政编码,网格,网格,经度,纬度

    用于获取ID和邮政编码的第一个查询的SQL

    从广告中选择ID和邮政编码,其中Make='$subMake'和Model='$subModel'

    SQL用于第二次查询,以使用符合距离要求的ID获取广告详细信息:

    SELECT Make, Model, Year, Engine, Colour FROM adverts WHERE ID IN(1,2,6,90,112,898)
    

    (很抱歉,若它的语法不正确,那个么它确实有效,SQL只是许多行查询字符串的粗略轮廓。)

    修改查询,使其包括邮政编码之间的距离,并仅限于指定距离范围内的广告。

    最大的优化是在插入广告行时查询邮政编码表并将网格引用存储在广告表中

    这将大大减少对post代码表的访问次数

    您还可以通过对广告表进行一些简单的过滤来减少计算量,如下所示

    从post code表中获取用户GridN和GridE值。 将minN计算为GridN-maxDistance,将maxN计算为GridN+maxDistance,将minE计算为GridE-maxDistance,将maxE计算为GridE+maxDistance

    然后,您可以像这样查询广告表:

    SELECT * FROM ADVERTS WHERE GridN between (minN,maxN) and GridE Between(minE,maxE);
    
    为了进一步加快速度,您可以向GridN和grid添加索引


    选择行后,您可以计算“实际”距离,并拒绝超出限制的少数行。

    您应该将距离函数更改为包含所有可能的邮政编码组合的视图,然后您可以在查询中加入该视图,而不是点击该函数,或者,您可以计算距离用户邮政编码50公里的纬度和经度


    此外,如果你提供固定选项(大多数网站只提供5、10、25、50、100作为距离选项),那么你可以预先计算这些距离计算,更进一步,你可以进行额外检查,并将每个邮政编码映射到附近的所有邮政编码,如果你真的需要,你只需要计算5次(5个距离)对于每个邮政编码,您可以从以前的值中排除结果,这样您就可以从10km查询中排除5km,因为您只是根据您的数据库查找距离,可能会使用类似PostGIS的东西

    在广告表中为LonLat数据类型设置一列,然后运行内置函数(如ST_DWithin),以查找与目标记录之间指定距离内具有LonLat的所有广告


    我发现使用静态邮政编码数据库的另一个问题是,它们很快就会过时(特别是对于新版本)。您可能还想使用Mapstraction之类的工具从Google/Yahoo等处返回地理编码结果,并保存该LonLat,尽管您可能需要对邮政编码输入进行更多的错误检查,并将返回的结果限制为精确匹配。

    从ID=1、ID=4和ID=23的广告中选择*
    肯定会成功始终返回0行?您的意思是从ID位于(1、4、23)中的广告中选择*