jjzjj

php - 从 Postcode DB 获取 lat/lng 并在 PHP/MYSQL 中按最近的顺序排序

coder 2023-10-26 原文

我正在使用 PHP 和 MYSQL 构建一个网站。

我正在尝试先按最近的位置对我的搜索结果进行排序。我有一个项目表和一个交易表。我需要在这两个表中搜索商品/交易位置,然后将位置与我的邮政编码数据库进行比较,并从相应的数据库条目中获取纬度和经度并对结果进行排序。我正在使用 PDO 准备好的语句。

我的数据库中有 3 个表。邮政编码、交易和元素。

邮政编码

| postcode | lat | lng |

交易

| id | title | location |

元素

| id | title | location |

这是我的 SQL...

SELECT SQL_CALC_FOUND_ROWS *
FROM (
    SELECT *
    FROM items
      UNION
    SELECT * FROM deals
) AS allitemsdeals
INNER JOIN (
    SELECT
        postcodes.*,
        (3959 * acos(cos(radians(custom.lat)) * cos(radians(postcodes.lat)) * cos(radians(custom.lng) - radians(postcodes.lng)) + sin(radians(custom.lat)) * sin(radians(postcodes.lat)))
        ) AS distance
    FROM postcodes
    INNER JOIN postcodes AS custom
    WHERE custom.postcode = ?
) postcodes ON allitemsdeals.location = postcodes.postcode
HAVING distance < 5 ORDER BY id LIMIT ? OFFSET ?

我的加入有问题。查询有效,但大约需要一分钟! :(

任何帮助将不胜感激!谢谢! :)

最佳答案

子查询正在扼杀您的性能。尝试在 SELECT 上添加 EXPLAIN 并查看输出 - 我怀疑有很多 USING FILESORTUSING (NULL) INDEX东西。并检查了很多记录。可能还有一些 derived 表...

所有这些 JOIN (SELECT ... 语句都会导致查询运行,结果被缓存(或者更糟的是仍然为 JOIN 左侧的每条记录重新运行) 没有任何索引 - 一切都可怕地停止了。

最后,SQL_CALC_FOUND_ROWS - 如果没有必要,请不要这样做。它会导致 MySQL 在应用 LIMIT 之前计算所有行并处理所有行以对它们进行计数。甚至在 LIMIT 之前尽可能减少结果会好得多 - 最好不要使用 SQL_CALC_FOUND_ROWS。 (一个单独的 SELECT COUNT(1) 会更好,相信我。去过那里。)

解决方案?不容易。从更改架构开始。

首先:我会将“交易”和“项目”合并到一个大表中 - 使用一列来区分类型(除非有很多其他列我不了解) 因为 UNION 可能(或肯定?)杀死您拥有的所有索引。

第二:距 ionic 查询 - 哦不!这应该是用于计算最大距离的直接 WHERE 子句。如果您愿意,我会尝试优化它 - 但是没有 SQLfiddle.com 或其他可以玩的东西,在我的空闲时间开始复制您的模式和数据有点多。 (如果你用它设置一个 SQLfiddle - 我会很乐意戳一下。)

第三:我会考虑使用 MySQL 的空间功能从 long/lat 数据开始。有很多可用的文档:

这是一些很酷的东西 - 我自己很长一段时间都想找借口在(付费!) 时间里玩弄这种数据。我很想知道您最终得到了什么解决方案。

正如我所说 - 如果您提供 SQLfiddle(假设其他人没有首先提供更好的解决方案),至少我会很乐意在接下来的 72 小时内查看。

关于php - 从 Postcode DB 获取 lat/lng 并在 PHP/MYSQL 中按最近的顺序排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33097847/

有关php - 从 Postcode DB 获取 lat/lng 并在 PHP/MYSQL 中按最近的顺序排序的更多相关文章

  1. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  2. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

  3. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  4. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  5. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

  6. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  7. ruby - 没有类方法获取 Ruby 类名 - 2

    如何在Ruby中获取BasicObject实例的类名?例如,假设我有这个:classMyObjectSystem我怎样才能使这段代码成功?编辑:我发现Object的实例方法class被定义为returnrb_class_real(CLASS_OF(obj));。有什么方法可以从Ruby中使用它? 最佳答案 我花了一些时间研究irb并想出了这个:classBasicObjectdefclassklass=class这将为任何从BasicObject继承的对象提供一个#class您可以调用的方法。编辑评论中要求的进一步解释:假设你有对象

  8. ruby-on-rails - 如何在 Gem 中获取 Rails 应用程序的根目录 - 2

    是否可以在应用程序中包含的gem代码中知道应用程序的Rails文件系统根目录?这是gem来源的示例:moduleMyGemdefself.included(base)putsRails.root#returnnilendendActionController::Base.send:include,MyGem谢谢,抱歉我的英语不好 最佳答案 我发现解决类似问题的解决方案是使用railtie初始化程序包含我的模块。所以,在你的/lib/mygem/railtie.rbmoduleMyGemclassRailtie使用此代码,您的模块将在

  9. ruby - 如何使用 CarrierWave 从 S3 获取真实文件 - 2

    我有一个应用程序可以读取文件的内容并为其编制索引。我将它们存储在磁盘本身中,但现在我使用的是AmazonS3,因此以下方法不再适用。事情是这样的:defperform(docId)@document=Document.find(docId)if@document.file?#Youshould'tcreateanewversion@document.versionlessdo|doc|@document.file_content=Cloudoc::Extractor.new.extract(@document.file.file)@document.saveendendend@docu

  10. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

随机推荐