首页 > 解决方案 > MariaDB 创建的视图耗时太长

问题描述

我有个问题。我有一张表,里面有 600 万条记录。每条记录都有一个日期时间列,对于我的代码,我需要按升序排列的最近 16 条记录。直接从原始表中查询花费的时间太长,因此我使用以下查询创建了一个视图:

SELECT openTime, high, low, a, b, c, d, e FROM  Candlestick WHERE market = 'USDT' AND coin = 'ETH' AND period = '5m' ORDER BY openTime DESC LIMIT 16

这意味着视图只包含 16 条记录。然后在我的代码中,我使用带有以下查询的视图:

SELECT high, low, a, b, c, d, e FROM vwCI_USDT_ETH_5m ORDER BY openTime ASC

此查询获取所有(16 条记录)记录并将其按升序排列,但即使对于这 16 行,查询也需要大约 25 秒,如下图所示: 在此处输入图像描述 有没有办法加快这个选择查询?

更新

我在 Candlestick 表上创建了一个索引,就像@The Impaler 告诉我的那样,我现在正在使用以下没有视图的查询:

SELECT a.high, a.low, a.a, a.b, a.c, a.d, a.e FROM (SELECT openTime, high, low, a, b, c, d, e FROM Candlestick WHERE market = 'USDT' AND coin = 'ETH' AND period = '5m' ORDER BY openTime DESC LIMIT 16 ) AS a ORDER BY a.openTime ASC

这是我现在所有的索引: 在此处输入图像描述 但是在索引之后,这个查询大约需要 20 - 25 秒。我能做些什么来改善它?

结果show create table Candlestick;

CREATE TABLE `Candlestick` (
  `dateTimeChanged` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
  `openTime` bigint(20) NOT NULL,
  `closeTime` bigint(20) NOT NULL,
  `market` varchar(10) NOT NULL,
  `coin` varchar(10) NOT NULL,
  `period` varchar(10) NOT NULL,
  `open` decimal(14,6) NOT NULL DEFAULT 0.000000,
  `high` decimal(14,6) NOT NULL DEFAULT 0.000000,
  `low` decimal(14,6) NOT NULL DEFAULT 0.000000,
  `close` decimal(14,6) NOT NULL DEFAULT 0.000000,
  `volume` decimal(20,8) NOT NULL DEFAULT 0.00000000,
  `a` decimal(6,3) NOT NULL DEFAULT 0.000,
  `b` decimal(3,0) NOT NULL DEFAULT 0,
  `c` decimal(3,0) NOT NULL DEFAULT 0,
  `d` decimal(3,0) NOT NULL DEFAULT 0,
  `e` varchar(1) NOT NULL DEFAULT '0',
  `ma5` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `ema5` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `ema10` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `ema12` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `ema20` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `ema26` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `ema50` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `ema55` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `ema100` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `ema200` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `rsi14AvgGain` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `rsi14AvgLoss` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `rsi14` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `macd` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `signal` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `bbLower` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `bbMiddle` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `bbUpper` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `dmiDIPositive` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `dmiDINegative` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  `dmiADX` decimal(16,8) NOT NULL DEFAULT 0.00000000,
  PRIMARY KEY (`openTime`,`market`,`coin`,`period`) USING BTREE,
  KEY `OpenTime` (`openTime`) USING BTREE,
  KEY `MarketCoinPeriod` (`market`,`coin`,`period`) USING BTREE,
  KEY `ix1` (`market`,`coin`,`period`,`openTime`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

标签: sqlmariadbquery-optimizationmariadb-10.3

解决方案


覆盖指数可能会有所帮助。

这是基于以下评论的最终建议索引:

create index ix3 on Candlestick (market, coin, period, openTime DESC, high, low, a, b, c, d, e);

这是测试用例中使用的所有 SQL(小提琴):

MariaDB 的工作测试用例和生成的样本数据

以下内容基于对实际create table陈述的猜测,但讨论一些可能的索引问题很有用。

这是带有当前建议索引的计划和一些示例数据:

在此处输入图像描述

这是descending索引版本的计划:

create index ix2 on Candlestick (market, coin, period, openTime DESC);

在此处输入图像描述

这是建议的覆盖指数:

create index ix3 on Candlestick (market, coin, period, openTime DESC, high, low, a, b, c, d, e);

在此处输入图像描述

并使用您的实际表和以前的ix1索引:

在此处输入图像描述

现在使用新的建议索引(有openTime DESC顺序):

在此处输入图像描述

更新:MariaDB 似乎支持降序索引语法,但可能不完全支持该功能。在较新的 Maria 版本(例如 10.5)中,新索引 ( ix3) 不用于此测试用例。

force如果发现有帮助,我们可以索引:

SELECT a.high, a.low, a.a, a.b, a.c, a.d, a.e
  FROM (
         SELECT openTime, high, low, a, b, c, d, e
           FROM Candlestick FORCE INDEX (ix3)
          WHERE market = 'USDT' AND coin = 'ETH' AND period = '5m'
          ORDER BY openTime DESC
          LIMIT 16
       ) AS a
 ORDER BY a.openTime ASC
;

如果我们在添加索引后查看表,我们会注意到该DESC术语被忽略:

KEY `ix3` (`market`,`coin`,`period`,`openTime`,`high`,`low`,`a`,`b`,`c`,`d`,`e`)

推荐阅读