【问题标题】:Does it improve performance to index a date column?索引日期列是否会提高性能?
【发布时间】:2014-01-23 04:40:48
【问题描述】:

我有一个包含数百万行的表,其中一列是 TIMESTAMP,我经常根据它选择日期范围。索引该列会提高性能,还是不会提供任何显着的改进?

编辑:

所以,我已经为 TIMESTAMP 列编制了索引。以下查询 select count(*) from interactions where date(interaction_time) between date('2013-10-10') and date(now())

需要 3.1 秒。

交互表中有超过 300 万条记录。

上面的查询产生了 ~976k 的结果

这似乎是执行此任务的合理时间吗?

【问题讨论】:

  • 性能优化是一门火箭科学。对于它目前提出的问题 - 无法判断它是否会使它变得更好或更糟。提供更多详细信息,包括您要优化的查询示例和表架构。
  • 对不起,这个问题是题外话,因为它不会帮助未来的访问者。问题至少需要您的表定义、查询和解释语句。这是真正可以自己测试的东西。
  • 为什么是-1?对我来说似乎是一个完全合理的问题(事实上,我发现了一个非常相似的问题,有 +3 票,它只是没有完全按照我的需要回答我的具体问题)。
  • 诸如“执行这项任务的时间是否合理?”等假设性问题是题外话。请参阅帮助中心。
  • @GeniaS。如果不知道您的硬件(CPU、RAM、磁盘 IO 等)和数据大小(100 行还是 1000 亿行?),就没有“合理的时间”,因此正如 FreshPrince 所指出的那样,这部分确实无法回答。另一部分,关于索引是否有帮助,可以(某种程度上)回答。

标签: mysql optimization indexing


【解决方案1】:

如果满足以下条件会提高性能:

  • 至少有“几个”不同的值
  • 您的查询使用的日期范围会选择少于“大多数”的行

要确定,请使用EXPLAIN 显示正在使用的索引。在创建索引之前和之后再次使用说明 - 您应该看到新索引是否正在使用。如果使用它,您可以确信性能会更好。

您也可以简单地比较查询时间。

【讨论】:

    【解决方案2】:

    对于

    select count(*) from interactions where date(interaction_time) between date('2013-10-10') and date(now())
    

    要优化的查询,您需要执行以下操作:

    1. 只使用interaction_time 而不是date(interaction_time)
    2. 创建一个涵盖interaction_time 列的索引
    3. (可选)仅使用'2013-10-10' 而不是date('2013-10-10')

    您需要 #1,因为仅当列按原样用于比较时才使用索引,而不是作为其他表达式中的参数。

    【讨论】:

      【解决方案3】:

      如果你想提高查询的效率,你需要做两件事:

      • 首先,索引列。

      • 其次,这一点更重要,确保您的查询条件是sargable,即可以使用索引。特别是,不应在列上使用函数。在您的示例中,编写条件的一种方法是:

        WHERE interaction_time >= '2013-10-10' 
          AND interaction_time < (CURRENT_DATE + INTERVAL 1 DAY)
        

      【讨论】:

      • 太棒了!这使它从 3.1 降低到 1.5 秒。
      • @Genia S.:选择了多少行(绝对值和百分比)? 1.5 秒是很多。全扫描与索引查询不应该相差 2 倍,这可能是由某些缓存引起的。
      • 结果略低于表格总行数的 1/3。我已经索引了interaction_time 列并按照打印的方式运行了您的查询。只是更改了日期以验证它没有被缓存,并且看起来它可能已经被
      • @Genia S.:为查询提供EXPLAIN
      • @RedBottleSanitizer 我是否正确理解您的 WHERE 类似于 WHERE a_col = 'sometext' AND b &gt;= '2020-01-01' AND c &lt;= '2022-12-31' ?在这种情况下,可能是 3 列索引 - (a,b,c) 或 (a,c,b) - 但取决于您的 DBMS,可能会有一些更好的解决方案。我建议你在 dba 网站上发布一个新问题:dba.stackexchange.com/questions/ask
      【解决方案4】:

      索引的一般规则是它们可以加快对大型数据集的数据检索,但会减慢记录的插入和更新。

      如果您有数百万行,并且需要选择其中的一小部分,那么索引很可能会在执行 SELECT 时提高性能。 (如果您需要其中的大部分或全部,则影响很小或没有影响。)

      如果没有索引,就会发生表扫描(即读取每条记录以定位所需的记录),这可能会很慢。 对于只有几条记录的表,表扫描实际上可以比索引快,但这不是您的情况。 另一个考虑因素是您有多少离散值。如果您只有少数几个不同的日期,那么索引可能根本无济于事,但是如果您的日期范围很广,那么索引很可能会有所帮助。 需要注意的是,如果索引非常大并且不适合内存,您可能无法获得您希望的性能优势。 此外,您还需要考虑您正在检索、连接等哪些其他字段,因为它们都会产生影响。 检查性能如何受到影响的一个好方法是使用 EXPLAIN 语句来查看 mySQL 将如何执行查询。

      【讨论】:

        【解决方案5】:

        在日期列上添加索引肯定会提高性能。

        我的表有 1100 万行,根据条件查询在特定日期更新的行需要以下时间:

        无索引:~2.5s

        带索引:~5ms

        【讨论】:

        • 我的查询使用 >= 和
        【解决方案6】:

        如果你想提高查询的效率,你需要做两件事:

        首先,索引列。

        其次,这一点更重要,确保查询的条件是可搜索的,即可以使用索引。特别是,不应在列上使用函数。在您的示例中,编写条件的一种方法是:

        WHERE interaction_time >= '2013-10-10' 
          AND interaction_time?
        

        【讨论】:

          猜你喜欢
          • 2014-11-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-26
          相关资源
          最近更新 更多