【问题标题】:How to calculate query time to decide which one is faster or more efficient?如何计算查询时间来决定哪一个更快或更高效?
【发布时间】:2021-12-15 09:54:28
【问题描述】:

我想比较我的算法,这是我的案例的一些简化, 假设使用 log_timestamp 列对表进行索引。

第一个查询:

SELECT
    name
FROM
    user_table
WHERE
    DATE(DATETIME_ADD(log_timestamp , INTERVAL 7 HOUR)) >= DATE('2018-01-01')
    AND 
    DATE(DATETIME_ADD(log_timestamp , INTERVAL 7 HOUR)) < DATE('2019-01-01');

第二次查询:

SELECT
    name
FROM
    user_table
WHERE
    log_timestamp >= DATETIME_SUB('2018-01-01', INTERVAL 7 HOUR)
    AND 
    log_timestamp < DATETIME_SUB('2019-01-01', INTERVAL 7 HOUR);

以上两个查询中哪个会更快,为什么?

【问题讨论】:

标签: mysql sql algorithm datetime where-clause


【解决方案1】:

要了解查询的运行速度是快是慢,我们必须知道表中有多少条记录。

如果记录数仍然在 100 - 1000 之间(取决于表中的字段数),则在执行两个查询时,两个查询几乎同时显示结果。

如果记录数超过100,000,就会开始看到显示结果的时间差。

记住,不要忘记使用 EXPLAIN 函数来查看查询的结果。

让我们分析一下这两个查询

第一次查询

SELECT
    name
FROM
    user_table
WHERE
    DATE(DATETIME_ADD(log_timestamp , INTERVAL 7 HOUR)) >= DATE('2018-01-01')
    AND 
    DATE(DATETIME_ADD(log_timestamp , INTERVAL 7 HOUR)) < DATE('2019-01-01');

MySQL 将:

  • DATE(DATETIME_ADD(log_timestamp , INTERVAL 7 HOUR)) 遍历表中的所有记录而不使用索引,
  • 之后 MySQL 将与 >= DATE('2018-01-01') 进行比较
  • DATE(DATETIME_ADD(log_timestamp , INTERVAL 7 HOUR)) 遍历表中的所有记录而不使用索引,
  • 之后 MySQL 将与 进行比较
  • 并显示结果 注意事项: 假设表中有 100,000 条记录,显示结果需要时间

第二次查询

SELECT
    name
FROM
    user_table
WHERE
    log_timestamp >= DATETIME_SUB('2018-01-01', INTERVAL 7 HOUR)
    AND 
    log_timestamp < DATETIME_SUB('2019-01-01', INTERVAL 7 HOUR);

MySQL 将:

  • 通过索引比较 log_timestamp >= DATETIME_SUB('2018-01-01', INTERVAL 7 HOUR),而不是全扫描表
  • 并比较 log_timestamp 通过索引,而不是全扫描表
  • 并显示结果

注意事项:

  • 记住!!!... 表格中的索引,就像书中的索引。当您想阅读超过 1000 页的书时,您将首先看到索引以找到您要查找的页面。您不会阅读所有页面,以找到您想阅读的主题。

【讨论】:

    【解决方案2】:

    您提出的问题实际上应该是两个独立的问题。首先,按照您上面所问的内容,现在这两个查询中的哪一个更快。第二个问题是真正需要考虑的问题,即如何调整这两个查询以使它们更快,以及哪一个最快。

    事实证明,只有第二个查询可以使用索引:

    SELECT name
    FROM user_table
    WHERE log_timestamp >= DATETIME_SUB('2018-01-01', INTERVAL 7 HOUR) AND 
          log_timestamp < DATETIME_SUB('2019-01-01', INTERVAL 7 HOUR);
    

    此查询应该受益于(log_timestamp, name) 上的索引。请注意,您的第一个查询不能真正受益于任何索引,因此我希望您的第二个查询在创建正确的索引后会快得多。

    【讨论】:

    • 谢谢,我对“索引”术语真的很陌生,你能详细说明一下吗?是不是因为第二个查询不需要对where子句做额外的计算和查找?
    • 尝试在谷歌上搜索“SQL inded tutorial”......您所问的问题需要一个正确的答案,无法在此处发表评论。
    猜你喜欢
    • 2012-08-16
    • 2011-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-05
    • 1970-01-01
    • 2011-05-23
    • 2019-11-13
    相关资源
    最近更新 更多