需要帮助优化 mysql 的纬度/经度地理搜索

2023-12-04

我有一个 mysql (5.0.22) myisam 表,其中大约有 300k 条记录,我想在 5 英里半径内进行纬度/经度距离搜索。

我有一个涵盖纬度/经度字段的索引,并且当我仅选择纬度/经度时速度很快(毫秒响应)。但是,当我选择表中的其他字段时,速度会严重减慢至 5-8 秒。

我正在使用 myisam 来利用全文搜索。其他索引表现良好(例如 select * from Listing where slug = 'xxxxx')。

如何优化查询、表或索引以加快速度?

我的架构是:

CREATE TABLE  `Listing` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(125) collate utf8_unicode_ci default NULL,
  `phone` varchar(18) collate utf8_unicode_ci default NULL,
  `fax` varchar(18) collate utf8_unicode_ci default NULL,
  `email` varchar(55) collate utf8_unicode_ci default NULL,
  `photourl` varchar(55) collate utf8_unicode_ci default NULL,
  `thumburl` varchar(5) collate utf8_unicode_ci default NULL,
  `website` varchar(85) collate utf8_unicode_ci default NULL,
  `categoryid` int(10) unsigned default NULL,
  `addressid` int(10) unsigned default NULL,
  `deleted` tinyint(1) default NULL,
  `status` int(10) unsigned default '2',
  `parentid` int(10) unsigned default NULL,
  `organizationid` int(10) unsigned default NULL,
  `listinginfoid` int(10) unsigned default NULL,
  `createuserid` int(10) unsigned default NULL,
  `createdate` datetime default NULL,
  `lasteditdate` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `lastedituserid` int(10) unsigned default NULL,
  `slug` varchar(155) collate utf8_unicode_ci default NULL,
  `aclid` int(10) unsigned default NULL,
  `alt_address` varchar(80) collate utf8_unicode_ci default NULL,
  `alt_website` varchar(80) collate utf8_unicode_ci default NULL,
  `lat` decimal(10,7) default NULL,
  `lon` decimal(10,7) default NULL,
  `city` varchar(80) collate utf8_unicode_ci default NULL,
  `state` varchar(10) collate utf8_unicode_ci default NULL,
  PRIMARY KEY  (`id`),
  KEY `idx_fetch` USING BTREE (`slug`,`deleted`),
  KEY `idx_loc` (`state`,`city`),
  KEY `idx_org` (`organizationid`,`status`,`deleted`),
  KEY `idx_geo_latlon` USING BTREE (`status`,`lat`,`lon`),
  FULLTEXT KEY `idx_name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=DYNAMIC;

我的查询是:

SELECT Listing.name, Listing.categoryid, Listing.lat, Listing.lon
, 3956 * 2 * ASIN(SQRT( POWER(SIN((Listing.lat - 37.369195) * pi()/180 / 2), 2) + COS(Listing.lat * pi()/180) * COS(37.369195 * pi()/180) * POWER(SIN((Listing.lon --122.036849) * pi()/180 / 2), 2) )) rawgeosearchdistance
FROM Listing
WHERE
    Listing.status = '2'
    AND ( Listing.lon between -122.10913433498 and -121.96456366502 )
    AND ( Listing.lat between 37.296909665016 and 37.441480334984)
HAVING rawgeosearchdistance < 5
ORDER BY rawgeosearchdistance ASC;

解释没有地理搜索的计划:


    +----+-------------+------------+-------+-----------------+-----------------+---------+------+------+-------------+
    | id | select_type | table      | type  | possible_keys   | key             | key_len |ref | rows | Extra       |
    +----+-------------+------------+-------+-----------------+-----------------+---------+------+------+-------------+
    |  1 | SIMPLE      | Listing    | range | idx_geo_latlon  | idx_geo_latlon  | 19      | NULL |  453 | Using where |
    +----+-------------+------------+-------+-----------------+-----------------+---------+------+------+-------------+
  

用地理搜索解释计划:



+----+-------------+------------+-------+-----------------+-----------------+---------+------+------+-----------------------------+
| id | select_type | table      | type  | possible_keys   | key             | key_len | ref  | rows | Extra                       |
+----+-------------+------------+-------+-----------------+-----------------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | Listing    | range | idx_geo_latlon  | idx_geo_latlon  | 19      | NULL |  453 | Using where; Using filesort |
+----+-------------+------------+-------+-----------------+-----------------+---------+------+------+-----------------------------+
  

这是带有覆盖索引的解释计划。以正确的顺序排列列会带来很大的不同:



+----+-------------+--------+-------+---------------+---------------+---------+------+--------+------------------------------------------+
| id | select_type | table  | type  | possible_keys | key           | key_len | ref  | rows   | Extra                                    |
+----+-------------+--------+-------+---------------+---------------+---------+------+--------+------------------------------------------+
|  1 | SIMPLE      | Listing | range | idx_geo_cover | idx_geo_cover | 12      | NULL | 453     | Using where; Using index; Using filesort |
+----+-------------+--------+-------+---------------+---------------+---------+------+--------+------------------------------------------+
  

谢谢你!


我认为你真的应该考虑使用PostgreSQL(与Postgis结合)。

由于以下原因,我(暂时)放弃了使用 MySQL 来处理地理空间数据:

  • MySQL仅支持MyISAM表上的空间数据类型/空间索引,具有MyISAM固有的缺点(关于事务、引用完整性......)
  • MySQL实现了一些OpenGIS 仅基于 MBR 的规格 (最小外接矩形)是 对于最严重的人来说毫无用处 地理空间查询处理(参见MySQL手册中的这个链接)。您很可能迟早会需要其中一些功能。

具有适当 (GIST) 空间索引和适当查询的 PostgreSQL/Postgis 可以非常快。

Example:确定“小”多边形选择和包含超过 500 万(!)非常复杂多边形的表之间的重叠多边形,计算这些结果 + 排序之间的重叠量。平均运行时间:30 到 100 毫秒之间(这台特定的机器当然有大量 RAM。不要忘记调整您的 PostgreSQL 安装...(阅读文档))。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

需要帮助优化 mysql 的纬度/经度地理搜索 的相关文章

  • PHP MySql 百分比

    我的问题是关于百分比 我不是专家 所以我会尽力以更好的方式进行解释 我的 mysql 服务器中有一个表 假设有 700 条记录 如下所示 Name country language Birth Lucy UK EN 1980 Mari Ca
  • 获取带有计数的不同记录

    我有一张桌子personid and msg列 personid msg 1 msg1 2 msg2 2 msg3 3 msg4 1 msg2 我想得到总计msg对于每个personid 我正在尝试这个查询 select distinct
  • 到 ToList() 还是不到 ToList()?

    给定一个在记忆中 不是 LINQ to SQL 类列表 List
  • 如何以最低的价格优化购物车?

    我有一个我想买的物品清单 这些商品由不同的商店提供 价格也不同 商店有单独的送货费用 我正在寻找一种最佳的购物策略 以及支持它的java库 以最低的总价购买所有商品 Example 商品 1 在 Shop1 的售价为 100 美元 在 Sh
  • 随机组合 MySQL 数据库中的两个单词

    我有一个包含名词和形容词的数据库 例如 id type word 1 noun apple 2 noun ball 3 adj clammy 4 noun keyboard 5 adj bloody ect 我想创建一个查询 它将抓取 10
  • PHP 与 MySQL 查询性能( if 、 函数 )

    我只看到这个artice http www onextrapixel com 2010 06 23 mysql has functions part 5 php vs mysql performance 我需要知道在这种情况下什么是最好的表
  • SQL 最近日期

    我需要在 php 中获取诸如 2010 04 27 之类的日期作为字符串 并在表中找到最近的 5 个日期 表中的日期保存为日期类型 您可以使用DATEDIFF http dev mysql com doc refman 5 1 en dat
  • SignalR 似乎正在减慢我的 MVC/Azure 应用程序的启动速度

    我有一个 MVC 应用程序在 Windows Azure 上的 WebRole 上的 NET 4 5 下运行 使用 SignalR 1 0 alpha2 并使用 ServiceBus 底板 在我的 App Start 文件夹中 我有 Reg
  • 如果 PyPy 快 6.3 倍,为什么我不应该使用 PyPy 而不是 CPython?

    我已经听到很多关于PyPy http en wikipedia org wiki PyPy项目 他们声称它比现有技术快 6 3 倍CPython http en wikipedia org wiki CPython口译员开启他们的网站 ht
  • 从前端更改记录顺序

    我在编写下一个功能时遇到问题 我希望用户能够重新排列记录并更改 display order 值 我使用 Jquery UI 的可拖放功能来促进这一点 我可以看到如何简单地交换 display order 值 但我想为一条记录设置一个显示顺序
  • mysql 版本号排序

    我有这样的价值观 1 1 2 9 1 2 2 4 1 2 3 4 3 2 14 3 2 1 4 2 我需要使用 mysql 对这些值进行排序 该数据类型是 varbinary 300 所需的输出将类似于 1 1 2 1 2 3 4 2 2
  • 删除连接中不存在的记录

    想象两个表 A 和 B A B 1 2 2 3 6 5 4 7 9 11 13 23 9 现在我想从 A 中删除 B 中不存在的记录 例如从 A 中删除 1 6 和 4 我最初的想法是您可以 否定 联接的结果 DELETE FROM A W
  • 如何获取日期时间字段的 UTC?

    我正在使用 MySQL 5 并且正在尝试将日期时间字段转换为 UTC TIMESTAMP 这是我所拥有的 但它不起作用 并且不确定我是否可以做到这一点 但有人可以告诉我我做错了什么吗 谢谢 我已经尝试过这个 SELECT UTC TIMES
  • 查询和扫描多行性能缓慢

    下面的查询一行的执行时间为 6 18 分钟 Exception type 1 的基数值为 3 我不知道如何提高性能 Query select count 1 as rage tap from summary funnel 1066 s jo
  • GWT 在开发模式下运行缓慢

    我在开发模式下使用最新的 GWT 2 0 版本的 Eclipse Galileo 但它运行速度非常慢 我需要等待大约一分钟才能打开一个页面 但编译后 当我使用 Tomcat 5 5 运行它时 我的应用程序运行得很好 我的代码不太重 我猜有一
  • Mathematica 使用符号而不是数字调用 NMinimize?

    我在使用时注意到以下行为NMinimize在数学中 目标函数的第一次调用是使用变量名称 而不是像人们所期望的那样使用空间中的点 因此 例如 如果我的目标函数是一个模块 则该模块仅被调用一次 进行符号评估 然后在进一步的迭代中 使用变量空间中
  • 如何将自托管 WordPress 和已安装的实时站点插件升级到最新可用版本而不遇到任何麻烦?

    我必须升级正在运行的 WordPress 网站的 WordPress CMS 和一些已安装的插件 并且我想要升级的一些插件之前已被修改以实现某些目标 http easycaptures com fs uploaded 288 9522279
  • Tomcat JDBC 池中没有足够的空闲连接

    给定以下 Tomcat JDBC 连接设置
  • vagrant box速度慢,如何改进?

    我们已经为我们的开发盒构建了一个 vagrant box 但我们面临着一些延迟问题 Issues Assetic 手表速度很慢 app dev php 中的整体应用程序访问速度很慢 在 vagrant box 的共享文件夹中使用 查找 命令
  • PostgreSQL 位图堆扫描索引非常慢,但仅索引扫描很快

    我创建了一个包含 43kk 行的表 并用值 1 200 填充它们 因此 表中每个数字大约为 220k create table foo id integer primary key val bigint insert into foo se

随机推荐

  • 查询列出所有存储过程

    什么查询可以返回 SQL Server 数据库中所有存储过程的名称 如果查询可以排除系统存储过程 那就更有帮助了 正如迈克所说 最好的方法是使用information schema 只要不在主数据库中 系统存储过程就不会被返回 SELECT
  • 在 sns.lmplot() 中格式化 x 轴(日期)

    我需要绘制每日数据sns lmplot 数据具有以下结构 df pd DataFrame columns date origin group value data 2001 01 01 Peter A 1 0 2011 01 01 Pete
  • 如何使用关键字作为属性名称?

    到目前为止 我已经非常成功地将匿名类型序列化为 json 了 dynamic jsObject jsObject new ExpandoObject jsObject dataUrl Controller Url Action loadal
  • Swift - 将字典 [String:Any] 编码和解码到 plist 中

    我试图将字典存储在我的 Marker 类中 但它抛出一个错误 指出它不可编码或可解码 我可以看到错误是由 String Any 引起的 但我该如何解决它 var buttonActions String String String Any
  • 如何在 CakePHP 中正确重写模型的构造函数

    我在 CakePHP 2 0 中测试模型时遇到了麻烦 问题似乎出在模型的构造函数上 public function construct parent construct this gt pagi cuantos 2 即使我删除了它的所有内容
  • R代码生成具有特定颜色的美国各州地图

    我正在尝试生成美国地图 其中每个州都可以具有以下颜色之一 EScolors lt c 7aad42 4a77bb f7931e d3dfbd 787878 我创建了一个数据框 states info 以将每个状态与其颜色相匹配 head s
  • 具有键“GenderID”的 ViewData 项的类型为“System.Int32”,但必须为“IEnumerable”类型

    当我尝试提交 发布数据时发生错误 有人可以帮助我尝试每一篇文章 但他们没有帮助我 我是 mvc 新手 任何帮助都会被授予 这是我的代码 public ActionResult Create UserProfileCreateViewMode
  • 将我的文本居中,但保持左对齐?

    我试图使页面上的链接左对齐但在页面上居中 我该怎么做呢 我尝试了很多方法 并在谷歌上搜索了更多我编码时间不长的方法 这正在成为一场真正的斗争 My site 这是我的 HTML 代码 img src http media moddb com
  • x86 中的原子测试和设置:内联 asm 或编译器生成的锁 bts?

    以下代码在为 xeon phi 编译时会抛出异常Error cmovc is not supported on k1om 但它确实可以为常规至强处理器正确编译 include
  • 双精度数中的小数位数[关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 如何确定数字中的整数位数和小数点后的位数234 12413在爪哇 双精度数并不总是精确的
  • 从 NSString 解析 XML 以获取值

    这个问题是关于在 xcode 中操作 NSString 的 我有一个从网上获得的 XML 文本字符串 如下所示
  • 使用给定的时间增量对时间序列进行重采样

    我正在使用 Pandas 来构建和处理数据 这是我的数据框 我想要对时间序列数据进行重新采样 并且对于每个 ID 此处命名为 3 从开始到结束 beginning time end time 的所有比特率分数 例如 对于第一行 我希望拥有从
  • 将值减去多行

    好吧 我陷入了需要将值分配到多行的地步 由于我不知道具体的术语 我将其以下面的示例的形式以便更好地理解 假设 x 的值为 20 我需要将其按降序分配 减去到行中 TABLE ID Value1 1 6 2 5 3 4 4 3 5 9 结果应
  • 将逗号后的数字四舍五入为 2 位数字

    我不知道该怎么做 我正在添加逗号数字 结果当然总是一个逗号后数字太多的数字 任何人 EDIT 2 Use the Number对象的toFixed像这样的方法 var num Number 0 005 The Number only vis
  • ggplot 中的数据重新排序

    新的并坚持使用 ggplot 我有以下数据 tribe rho preference watermass 1 Luna2 1 000 hypolimnic 2 OP10I A1 1 000 epilimnic 3 B0 FO56C 0 98
  • 从 @selector 中关闭视图控制器而不创建单独的方法

    我试图通过直接从按钮执行它来关闭呈现的视图控制器 而不是为其创建一个单独的方法 但我不知道如何让它工作 或者是否可能 如有任何帮助 我们将不胜感激 我正在尝试的代码 dismissButton addTarget self action s
  • 从 SQL Server 触发器发送消息

    当 SQL Server 2005 中发生某些事情时 我需要向正在运行的应用程序 Windows 服务 发出信号 是否可以将消息从触发器发送到同一系统上的外部应用程序 您可以使用SQL 服务代理排队做你想做的事 触发器可以创建对话并在队列上
  • 如何使 DrawerLayout 显示在工具栏下方?

    如何使抽屉布局位于操作栏 工具栏下方 我正在使用 v7 21 应用程序兼容库和新的工具栏视图 我看到的例子看起来像
  • 在 pyinstaller 生成的可执行文件中使用 pyunpack 并结合 try except

    我对 pyunpack 有一个奇怪的行为 pyunpack 是一个在可执行文件内用于解包的包 我想做以下事情 我有一个 7z 类型的文件 其结尾不是 7z 而是 sent 首先 我尝试直接解压缩它 这会导致捕获预期的错误 在这个错误捕获中
  • 需要帮助优化 mysql 的纬度/经度地理搜索

    我有一个 mysql 5 0 22 myisam 表 其中大约有 300k 条记录 我想在 5 英里半径内进行纬度 经度距离搜索 我有一个涵盖纬度 经度字段的索引 并且当我仅选择纬度 经度时速度很快 毫秒响应 但是 当我选择表中的其他字段时