MYSQL 使用空间索引

2024-03-26

我正在尝试利用空间索引。我有一个 ip 表和一个包含 ip 块范围的 ip2geo 表。我正在尝试将 Geo ID 分配给 ip2geo 表中的每个 ip

当尝试使用列值进行选择时,空间索引不会被使用。

EXPLAIN
SELECT *,
   ( SELECT locid FROM  `ipblocks` i  
     WHERE MBRCONTAINS(i.ippolygon, 
                       POINTFROMWKB(POINT(h.`ip`,   0))) ) AS locaid 
FROM `ips` h  LIMIT 1;  


    id          select_type table   type    possible_keys       key     key_len ref     rows    Extra
    1           PRIMARY     h       ALL     NULL                NULL    NULL    NULL    33279   2   DEPENDENT
    SUBQUERY    i                   ALL     ipblock_spatialidx  NULL    NULL    NULL    4977388 Using where
  

当在过滤器中使用常量时,会使用索引。

EXPLAIN SELECT *,(SELECT locid FROM  `ipblocks` i  WHERE
MBRCONTAINS(i.ippolygon, POINTFROMWKB(POINT(3223394542, 0))) ) AS
locaid FROM `ips` h  LIMIT 1;  


id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY h   ALL NULL    NULL    NULL    NULL    33279   Using filesort 2    UNCACHEABLE
SUBQUERY    i   range   ipblock_spatialidx  ipblock_spatialidx  34  NULL    1   Using where

当内部连接时使用索引(检查额外)

EXPLAIN SELECT * FROM `ips` h INNER JOIN `ipblocks` i ON (MBRCONTAINS(i.ippolygon, POINTFROMWKB(POINT(h.`cp`, 0)))) LIMIT 100 ;

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  h   ALL NULL    NULL    NULL    NULL    33279   
1   SIMPLE  i   ALL ipblock_spatialidx  NULL    NULL    NULL    4977388 

检查每条记录的范围(索引图:0x1)

左连接时不使用索引。

EXPLAIN SELECT * FROM `ips` h LEFT JOIN `ipblocks` i ON (MBRCONTAINS(i.ippolygon, POINTFROMWKB(POINT(h.`ip`, 0)))) LIMIT 100 ;

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  h   ALL NULL    NULL    NULL    NULL    33279   
1   SIMPLE  i   ALL ipblock_spatialidx  NULL    NULL    NULL    4977388

如何优化 SQL 查询以使用空间索引?

UPDATE:

我能够使用插入触发器快速分配 GEO 国家/地区。但我仍然需要知道为什么在加入或子查询时不能使用空间索引

BEGIN
DECLARE geoloc VARCHAR(10) DEFAULT NULL;

SELECT country FROM  ipblocks i LEFT JOIN iplocations l ON(i.locid=l.locid)  WHERE  MBRCONTAINS(i.ippolygon, POINTFROMWKB(POINT(NEW.ip, 0))) LIMIT 1 INTO geoloc;
SET NEW.geo= geoloc;

END

更新 2 @John 的问题

我的目标是抢到一张桌子IPs具有以下架构

username, ipaddress, country

并使用我购买的 GEO2IP 表,该表附带 IP 范围作为 INET_ANOT() 表IPblocks

ipfrom,ipto,country,poly  [example POLYGON((16777216 -1,16777471 -1,16777471 1,16777216 1,16777216 -1)) ]

现在,如果不创建触发器或存储过程,我如何更新表中的国家/地区IPs使用地理空间索引ipblocks

最后更新(承诺)使用过的溶液

SELECT *  FROM `iplist` i  LEFT JOIN `iplocations` l ON (SELECT GetLocId(INET_ATON(i.`ip`))=l.`locid`) ;

GetLocId 使用以下 SQL

SELECT locid FROM  `ipblocks` i  WHERE
MBRCONTAINS(i.ippolygon, POINTFROMWKB(POINT(@INPUTVAR,   0))) INTO locid

并返回locid,它在39ms内匹配了40k ips


不幸的是,您所看到的是 MySQL 中空间函数实现方式的普遍问题以及涉及空间函数的子查询的相关弱点。

为了使 Contains 和 Intersects 函数正常工作以及要使用的索引,您需要其中一个几何形状是常数。尽管您将看到的 MySQL 与 Intersects/Contains 的所有示例都是以这种方式工作的,但这似乎没有记录在案。

因此,您不能像在 Oracle Spatial 或 Postgis 中那样编写这样的内容,

select a.*, b.* 
from sometable a, someothertable b 
where ST_Intersects(a.geom, b.geom) 
and a.someattribute=... and b.someattribute=...;

在这样的查询中,如果表 a 和 b 都有空间索引,则将使用它们,前提是这比您可能放入 where 子句中的其他属性更具限制性。

这同样适用于自连接,您希望根据某些属性查找与表中所有其他多边形相交的所有多边形,例如,

select a.* 
from sometable a, sometable b 
where ST_Intersects(a.geom, b.geom) ....

因此,在 MySQL 空间中,您被迫让其中一个几何图形成为常量。

顺便说一句,左连接语法对于空间没有多大意义(尽管它是受支​​持的),因为您并不是真正在单个匹配的属性上连接,而是在二维包含/交集运算符上连接。

另外,我很确定在您的内部联接中没有使用索引,如果您查看key and rows解释的输出。

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

MYSQL 使用空间索引 的相关文章

  • WordPress 访问

    我正在与朋友一起开发一个网站 使用Wordpress我们正在尝试从我的计算机和他的计算机访问同一个 WordPress 帐户 以便我们可以一起在网站上工作 我们尝试将彼此添加为管理员 但只能从创建管理员的计算机上访问新帐户 有谁知道如何做到
  • 带有 viewbags 的 MVC 数据集

    如何将数据集放入视图袋中并在视图中显示结果 我有一个来自模型的数据集 并将其写入视图包 我想使用 foreach 循环从视图中的视图包中获取数据行 我已经有一个变量进入视图 所以我无法正常传递数据集 每页我还会有许多其他数据集 所以我认为
  • 显示多个表的账户余额

    我有以下两个表 其中存储有关贷记和借记记录的信息 couponCr 表包含 voucherType voucherPrefix voucherNo crparty cramount SALES S 1 1 43000 SALES S 2 1
  • MySQL 如何使用返回多行的 SELECT 子查询插入表?

    MySQL 如何使用返回多行的 SELECT 子查询插入表 INSERT INTO Results People names VALUES SELECT d id FROM Names f JOIN People d ON d id f i
  • 从Oracle表中删除重复行

    我正在 Oracle 中测试某些内容并使用一些示例数据填充表 但在此过程中我不小心加载了重复记录 因此现在我无法使用某些列创建主键 如何删除所有重复行并只保留其中一行 Use the rowid伪列 DELETE FROM your tab
  • SQL Not Empty 代替 Not NULL

    我正在使用 postgreSQL 我有一个专栏 NOT NULL 但是 当我想插入带有空字符串的行时 如下所示 它不会给我错误并接受 我如何检查插入值应该是not empty 既不为空也不为空 PS 我的专栏定义为 ads characte
  • 单向关系和双向关系的区别

    我想知道这两个词是什么意思 我遇到他们是在教义的文档 http www doctrine project org documentation manual 2 0 en association mapping 但我不明白他们的意思 这与常见
  • 出于安全目的,您是否有理由不执行自己的算法来打乱 ID?

    我计划实现我自己的非常简单的 哈希 公式 为具有多个用户的应用程序添加一层安全性 我目前的计划如下 用户创建一个帐户 此时后端会生成一个 ID ID 通过公式运行 假设 ID 57 8926 36 7 或同样随机的东西 然后 我将新的用户
  • 如何重命名 SQL Server 中名称中带有方括号的内容?

    我的一张桌子上有一列 周围有方括号 Book Category 我想重命名为Book Category 我尝试了以下查询 sp rename BookPublisher Book Category Book Category COLUMN
  • 使用子查询与 LEFT JOIN 一起选择 MAX 值

    我有一个获取搜索结果的查询 效果很好 查询成功示例 SELECT individuals individual id individuals unique id TIMESTAMPDIFF YEAR individuals day of b
  • 如何在数据库中对 (Java) 枚举进行建模(使用 SQL92)

    您好 我正在使用名为 性别 的列对实体进行建模 在应用程序代码中 性别应该是一个 Java 枚举类型 有 2 个值 男性和女性 知道作为数据类型的枚举不是通用 SQL 语言 92 的一部分 您将如何建模它 数据模型必须是可移植的 以便由多个
  • 使用 Laravel Fluent 查询生成器从多个表中进行选择

    我正在重写一些 PHP MySQL 来与 Laravel 一起使用 我想做的一件事是使数据库查询更加简洁使用 Fluent 查询生成器 http laravel com docs database fluent但我有点迷失 SELECT p
  • 从本地 html/javascript 网站插入 mySQL 数据库

    我正在尝试做什么 我的程序的目的是插入数据local HTML JS网站变成online 非本地 mySQL数据库 到目前为止我尝试过的 我试图用来实现此目的的原始方法是让我的本地网站使用 javascript 通过在线发布数据PHP文件
  • MySQL ALTER TABLE 挂起

    我知道这个问题已经被问过好几次了 但我的问题发生在我刚刚创建的表上 它只有 10 列和 1 行 因此 与通常的挂起问题不同 这不是具有大量数据的大表的情况 但它仍然挂着 这是我正在运行的 SQL ALTER TABLE db Search
  • 无法将方法组“Read”转换为非委托类型“bool”

    我正在尝试使用SqlDataReader检查条目是否存在 如果存在则返回ID 否则返回false 当我尝试编译时 出现错误 无法将方法组 Read 转换为非委托类型 bool 我一直在遵循在 VB 中找到的示例 但似乎翻译可能不正确 pri
  • 在单个查询中设置和选择?

    我想知道是否可以在单个查询中设置和选择 像这样的事情 SET LOCAL search path TO 1 SET LOCAL ROLE user SELECT from posts 你可以这样做 with some set as sele
  • Mysql:计算访问频率

    我有这张桌子 CREATE OR REPLACE TABLE hits ip bigint page VARCHAR 256 agent VARCHAR 1000 date datetime 我想计算每个页面的 googlebot 访问频率
  • 如果不存在则插入数据(来自 2 个表),否则更新

    再会 我有3张桌子 tbl仓库产品 ProductID ProductName ProductCode Quantity tbl分公司产品 ProductID ProductCode ProductCode Quantity Locatio
  • 测验程序的 MySql 数据库设计

    我目前正在开发一个项目 主要是创建一个测验应用程序 它将能够进行包含 10 到 20 个问题的多项选择题或简答题的测验 它需要能够根据正确答案检查用户的答案 然后对用户的答案进行评分 稍后 我可能会实现一个后端功能来在线创建测验 但现在我将
  • 多个数据库连接

    我有三张桌子 categories content info and content The categories表包含类别的id及其 IDparent类别 The content info包含两列 entry id帖子的 ID 和cat

随机推荐

  • wordpress 插件 -> 调用未定义函数 wp_get_current_user()

    我正在尝试使用函数 wp get current user 获取插件中的当前用户信息 但我越来越Call to undefined function wp get current user 显然发生这种情况是因为文件 wp includes
  • 如何路由用户配置文件 URL 以跳过控制器?

    现在我的用户个人资料 URL 如下所示 http example com users joeschmoe http example com users joeschmoe 这表明show用户控制器中的方法 我理想的做法是提供这样的用户个人资
  • Winforms DataGridView 中的超链接单元格

    我有一个包含以下数据的 datagridview ContactType Contact Phone 894356458 Email email protected cdn cgi l email protection 在这里 我需要显示数
  • 是否可以为每个商店定义 Magento 布局更新

    我有一个 Magento 安装运行两个不同的网站 一个销售电子书 另一个不销售 因此业务团队希望看到 我的下载 链接从应用程序 我的帐户 区域的客户导航块中删除 我可以看到 design frontend base layout downl
  • AttributeError:模块“keras.engine”没有属性“input_layer”

    我正在尝试使用谷歌colab 但我一直遇到 keras 的问题 它说 AttributeError 模块 keras engine 没有属性 input layer 然而 检查他们的github库 keras engine中有一个input
  • go build 与 strip 的 golang strip 符号

    为什么剥离符号不同strip and go build ldflags s w see here https stackoverflow com questions 29599209 how to build a release versi
  • Android:startActivityForResult 的 resultCode 总是为 0? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 由于某种原
  • 在rails控制台中查看回滚错误的原因

    我正在尝试通过 Rails 控制台更新记录 但收到回滚错误 Project find 118 update attributes featured gt true Project Load 2 6ms SELECT projects FRO
  • 从下到上显示活动

    我想展示一个activity到另一个从下到上的动画使用Intent 给我一些例子 如下所示 Intent i2 new Intent main this test class startActivity i2 从下到上有动画 在 res a
  • Linq - 在列表中按周分组

    我想按周对我的数据进行分组 如下所示 var result stats GroupBy i gt SqlFunctions DatePart week i date Select g gt new ReportModel clicks g
  • 如何计算两个单词之间的相似度以检测它们是否重复?

    我有两个单词 我想计算它们之间的相似度 以便对它们是否重复进行排名 如何使用深度学习 NLP 方法实现这一目标 这里有一些解决文本相似性的方法 基于字符串的方法 给定 2 个句子字符串计算余弦相似度 https stackoverflow
  • array_key_exists 不起作用

    array key exists 不适用于大型多维数组 对于前 arr array 1 gt 10 2 gt array 21 gt 21 22 gt 22 23 gt array test gt 100 231 gt 231 3 gt 3
  • 嵌入时间线中的多个推特提要

    我现在正在开发一个网站 其中会有多个公司简介 每个个人资料都需要有一个 Twitter feed 并且在每个 feed 中我需要能够包含至少 2 个 Twitter 用户的推文 正在分析的公司和网站的 feed 本身 可能还有第三个 我有点
  • 提示用户输入密码 - Google OpenID Connect

    我们正在尝试将 Google 的 OpenID Connect 用于商业网络应用程序 但担心用户会使应用程序保持打开状态 并且未经授权的用户将登录 因为用户仍然登录到 Google 因此 OpenID Connect 只是让他们直接登录 W
  • 如何从多个线程同时访问MySQL

    我们正在对 MySQL 进行一个小型基准测试 希望了解它对我们的数据的执行情况 该测试的一部分是看看当多个并发线程用各种查询攻击服务器时它是如何工作的 The MySQL 文档 http dev mysql com doc refman 5
  • 如何使用rest api将数据集作为csv文件导入到power bi?

    我想在 power bi 中自动执行导入过程 但我找不到如何将 csv 文件发布为数据集 我正在为此使用 C 解决方案 有没有办法做到这一点 您无法将 CSV 文件直接导入到 Power BI 服务中已发布的数据集 AddRowsAPIEn
  • 如果时区设置为“UTC”,SimpleDateFormat 会忽略“XXX”

    我正在尝试按以下格式将当前日期时间输出为 UTC 2016 01 11T14 08 42 00 00 final SimpleDateFormat formatter new SimpleDateFormat yyyy MM dd T HH
  • PHP 的项目结构

    我是 PHP 新手 想了解 php 项目的目录结构 我有Java方面的经验 在java中我们有src包含java源文件 WEB INF包含lib和jsp页面 PHP 中有类似的标准目录结构吗 我们在 php 中也有分层吗 就像我们在 jav
  • Python 现在或将来会弃用“pytz”吗?

    pytz https pytz sourceforge net 用于Django 版本 选择当前时区 https docs djangoproject com en 3 2 topics i18n timezones selecting t
  • MYSQL 使用空间索引

    我正在尝试利用空间索引 我有一个 ip 表和一个包含 ip 块范围的 ip2geo 表 我正在尝试将 Geo ID 分配给 ip2geo 表中的每个 ip 当尝试使用列值进行选择时 空间索引不会被使用 EXPLAIN SELECT SELE