为表创建好的索引
Posted
技术标签:
【中文标题】为表创建好的索引【英文标题】:Creating good indexes for table 【发布时间】:2019-12-07 02:35:54 【问题描述】:我正在使用 MariaDB (mysql) 表,其中包含有关一些地图点(纬度和经度)和数量的信息。
我正在做很多查询来检索其中的一些点,我想优化查询使用索引。不知道怎么做好。
我的查询是这样的:
SELECT p.id, p.lat, p.lon, p.quantity
FROM Points p
WHERE ((p.lat BETWEEN -10.0 AND 50.5) AND
(p.lon BETWEEN -30.1 AND 20.2) AND
(100 <= p.quantity AND 2000 >= p.quantity))
ORDER BY p.name DESC;
因此,查询中涉及的列是:lat
、lon
和 quantity
。
谁能帮帮我?
【问题讨论】:
看看ST_WITHIN和SPATIAL INDEX 【参考方案1】:折腾你有的索引,并添加这些:
INDEX(lat, lon),
INDEX(lon, lat),
INDEX(quantity)
提供了一些讨论here
【讨论】:
【参考方案2】:当你有多个范围条件时,即使你对所有列都有一个标准的B树索引,你也只能得到一个索引来优化第一个范围条件。
WHERE ((p.lat BETWEEN -10.0 AND 50.5) -- index on `lat` helps
AND (p.lon BETWEEN -30.1 AND 20.2) -- no help from index
AND (100 <= p.quantity AND 2000 >= p.quantity)) -- no help from index
您可以为lat
编制索引,也可以为lon
编制索引,也可以为quantity
编制索引,但您的查询将只能使用B-tree 索引来优化这些条件之一。
这就是@achraflakhdhar 的回答是错误的原因,也是@duskwuff 的回答建议使用空间索引的原因。
空间索引不同于 B 树索引。空间索引旨在帮助这种情况,您需要二维的范围条件。
很抱歉,这听起来会导致您的项目返工,但如果您希望对其进行优化,那就是您必须做的。
【讨论】:
谢谢。我想我会创建一个新的点列和一个触发器,在创建行时将空间信息添加到列中 我发现INDEX(lat, lon)
比INDEX(lat)
好是因为ICP。【参考方案3】:
你想要的是一个空间索引。您将需要更改表的架构(通过将 lat
和 lon
转换为单个 POINT
或 GEOMETRY
值)来支持这一点,并使用特定的函数来查询该值。完成此操作后,您可以使用CREATE SPATIAL INDEX
创建空间索引;此索引将允许您针对该值执行各种高度优化的查询。
有更多关于在 MySQL in the "Spatial Data Types" section of the MySQL manual 中使用空间类型的信息。
【讨论】:
谢谢!但我认为我必须在一个巨大的项目中做出很多改变:( 不幸的是,如果您需要针对此表优化空间查询,这将很难避免。 谢谢。我想我会创建一个新的点列和一个触发器,在创建行时将空间信息添加到列中 迁移完成后...是否可以索引两列(坐标和数量)?以上是关于为表创建好的索引的主要内容,如果未能解决你的问题,请参考以下文章