【问题标题】:Mysql index on values != 0Mysql索引值!= 0
【发布时间】:2014-06-05 11:52:23
【问题描述】:

我有一个包含事件的大表。他们中的大多数都有经度+纬度。但有些没有。

当我查找事件列表时,我总是包含 WHERE longitude!=0 AND latitude!=0

是否有可能在索引中或通过其他方式有一个预过滤器来消除非地理定位事件。

PS:我需要将那些非地理定位事件保留在我的表中。

SELECT * FROM events WHERE start_time > NOW() AND latitude != 0 AND longitude != 0  

【问题讨论】:

  • 如果您有不知道纬度和经度的事件,将它们存储为 NULL 可能比 0 更合适。0 是纬度和经度的合法值。 NULL 表示“不知道”或“没有值”。
  • 这是有道理的。我想知道在 Non NULLS 上进行搜索是否比在 != 0 上进行搜索更快
  • 它可能会让事情变得更快一点,是的(因为 NULL 值可能没有存储在索引中,因此必须在索引中检查更少的值),但这不是你应该这样做的原因用来做开关。这只是一个快乐的副作用。 (但我不能权威地谈论 MySQL 如何对 NULL 值进行索引)

标签: mysql database-indexes


【解决方案1】:

在大多数情况下,索引不会对性能产生影响。主要问题是选择性。也就是说,有多少比例的事件是地理定位的,多少比例没有。

扫描一张表时,数据库需要读取所有的页面。索引使事情变得更快的一种方法是减少需要读取的页面数量。但是,这可能是违反直觉的。如果一个典型的记录是 80 个字节,那么每页大约可以容纳 100 个。因此,即使只有 5% 的事件是地理定位的,也很有可能需要阅读所有页面。平均页面将有 5 条这样的记录。换句话说,索引并没有节省多少工作(甚至可能导致更多工作,但这是另一个问题)。

对此有一些警告。在表上创建带有“地理定位”标志的主键索引作为第一个元素会影响页面布局。除了最多一个之外的所有页面都将只有地理定位记录或非地理定位记录。这将提供性能提升。

对于您的特定查询,最佳索引可能是events(start_time)。因为select *,查询无论如何都需要去数据页取数据,可以同时返回经纬度。

【讨论】:

  • 在我的例子中,有很多项目从很多不同的时间开始,我认为按时索引会创建太大的索引(尤其是在时间戳上)。但是感谢您的详细解释。
【解决方案2】:

我认为这里最好的答案是创建一个视图。您可以以与表几乎相同的方式与视图交互(INSERT、UPDATE、DELETE 等),但您可以选择该表的子集在视图中进行交互。这是创建语法:

CREATE VIEW [you view name] AS
SELECT * FROM events WHERE start_time > NOW() AND fblatitude != 0 AND fblongitude != 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多