【问题标题】:Mysql query takes too much time with IndexMysql查询需要太多时间索引
【发布时间】:2019-10-26 16:55:12
【问题描述】:

我的查询在索引上花费了太多时间。 如何为我的 Mysql 查询创建一个好的索引?

查询

SELECT `id`, `time`, `volume`, `candle` FROM `forex_history` 
WHERE 
   period='30m' AND 
   id IN ('40','1817') 
   ORDER BY `time` DESC 
LIMIT 600;

表格中有 9500 万行

慢查询日志:

# Query_time: 3.801843  Lock_time: 0.000076  Rows_sent: 600  Rows_examined: 10966
# Rows_affected: 0  Bytes_sent: 49296

10% 的查询速度很慢。 查询需要 0.2 秒到 30 秒

表架构:

执行计划:

【问题讨论】:

  • 运行explain select ...查看执行计划。
  • 我今天才学习“解释选择...”,你能帮我检查一下它的结果吗..谢谢。截图prntscr.com/pooyu7

标签: mysql


【解决方案1】:

我可以建议以下索引:

CREATE INDEX idx ON forex_history (period, time, volume, candle);
-- add id if not using InnoDB

该索引将涵盖整个WHERE 子句以及SELECT

您可以尝试其他两个版本:

(period, id, time, volume, candle)
(period, id, time)

【讨论】:

  • 我知道这行不通,但请尝试一下,结果是“不工作”。我没有投反对票,但列名不能是索引,索引仅适用于 where 子句。如果您认为,请说明,选择列可以在索引中。
  • @FaisalAbbas 您对索引如何工作的理解还很遥远,从您的评论中可以看出。因为您的选择仅包含 4 列,所以我选择通过将所有列都包含在索引中来覆盖这些列。
  • 其实可能行不通,但我给出的答案是在不知道你的数据、它的基数等的情况下合理猜测。
  • 你的索引是活跃的,但是我没有删除我的旧索引,我明天更新你,如果查询日志,记录慢查询。我担心如果我删除我的索引,我的服务器会因为查询负载过重而死。
  • 没有我的索引查询需要 50+ 秒才能加载。
【解决方案2】:

我同意蒂姆的回答...最具体地说是 (period, id, time) 上的索引。

此外,由于您的“id”列是整数,因此请去掉引号,使其成为隐含的​​字符串。让数据类型正确以防止类型/转换混淆。

SELECT id, time, volume,  candle 
   FROM forex_history
   WHERE period='30m' 
      AND id IN ( 40, 1817 ) 
   ORDER BY time DESC 
   LIMIT 600;

现在,正如 Tim 还提到的基数一样,我们对基数和您的数据集一无所知。你可能最好做一个 UNION,然后限制。这就是为什么。您有 95+ 百万条记录。假设 ID 40 有 180k 条记录,id 1817 有另外 90k 条记录。您必须先拉下超过 270k 条记录,然后才能应用订单。

如果您进行联合,其中每个 ID 的限制为 600,您将获得最多 1200 条记录,然后这 1200 条记录按其各自的最佳时间降序排序,即使对于给定 ID 来说都是单边的.

SELECT 
      id, time, volume,  candle 
   from
      ( SELECT id, time, volume,  candle 
           FROM forex_history
           WHERE period='30m' 
              AND id = 40 
           ORDER BY time DESC 
           LIMIT 600
        UNION ALL
        SELECT id, time, volume,  candle 
           FROM forex_history
           WHERE period='30m' 
              AND id = 1817
           ORDER BY time DESC 
           LIMIT 600 ) PQ
   order by time desc
   limit 600

【讨论】:

    【解决方案3】:

    将时间转换为数字并按时创建索引。

    【讨论】:

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