为表创建好的索引

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;

因此,查询中涉及的列是:latlonquantity

谁能帮帮我?

【问题讨论】:

看看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】:

你想要的是一个空间索引。您将需要更改表的架构(通过将 latlon 转换为单个 POINTGEOMETRY 值)来支持这一点,并使用特定的函数来查询该值。完成此操作后,您可以使用CREATE SPATIAL INDEX 创建空间索引;此索引将允许您针对该值执行各种高度优化的查询。

有更多关于在 MySQL in the "Spatial Data Types" section of the MySQL manual 中使用空间类型的信息。

【讨论】:

谢谢!但我认为我必须在一个巨大的项目中做出很多改变:( 不幸的是,如果您需要针对此表优化空间查询,这将很难避免。 谢谢。我想我会创建一个新的点列和一个触发器,在创建行时将空间信息添加到列中 迁移完成后...是否可以索引两列(坐标和数量)?

以上是关于为表创建好的索引的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 反向主键

如果我在 sql server 中为表创建索引,看起来索引表的视图会受到影响吗?

是否为表中的每个外键隐式创建了非聚集索引?

为表建立索引

21年数据库考试复习题目

21年数据库考试复习题目