MySQL使用where子句在max和min列上建立索引

时间:2020-01-25 17:56:44

标签: mysql indexing

我有可以创建的表

CREATE TABLE 
`1m_candles` (`exchange_name` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
              `market_name` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
              `open` decimal(20,8) unsigned DEFAULT NULL,
              `high` decimal(20,8) unsigned NOT NULL,
              `low` decimal(20,8) unsigned NOT NULL,
              `close` decimal(20,8) unsigned DEFAULT NULL,
              `time` datetime NOT NULL,
              PRIMARY KEY (`exchange_name`,`market_name`,`time`),
              KEY `make_candles` (`exchange_name`, `market_name`, `time`, `high`, `low`)
             ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

而我在下面经常使用这样的查询。

SELECT MAX(`high`), MIN(`low`) 
FROM `1mi_candles` 
WHERE exchange_name = 'BINANCE' 
  AND market_name = 'ADABTC' 
  AND `time` >= '2020-01-01 00:00:00' 
  AND `time` < '2020-01-03 00:00:00'

我将主键用于唯一行(exchange_name,market_name和time)。

我的索引真的有用吗?这是我创建密钥的正确方法吗?

1 个答案:

答案 0 :(得分:2)

您的PRIMARY KEY实际上是最好的。添加的KEY不足以使情况值得增加。

拥有AUTO_INCREMENT会很浪费,因为您有一个非常好的“自然”主键。

应用程序中,可以在唯一(或主)键中使用DATETIME。但是,这假设您在相同的 second 内从未有两次报价的读数。如果您要捕获每笔交易,则需要重新解决。

如果该表在很多天内都有许多行情收录器,则该表将很大。如果您担心表的大小,请考虑:

  • 可以删除二级索引(如上所述)。

  • decimal(20,8)似乎有点过分。它占用10个字节。

  • 交易所和market_name可以归一化到另一个表中,用一个3字节的MEDIUMINT UNSIGNED代替。

表名称为“ make_candles”。这是否意味着您将绘制“蜡烛”图?这意味着您需要每个股票行情指标的每个时间单位的高,低,开和关。如果这涉及收集一千行以制作每个蜡烛,那么我们应该讨论“汇总表”以获取每个蜡烛的足够信息。总结和汇总每天的高,低,开盘价和收盘价非常容易,例如每天或每月的高,低,开盘价和收盘价。

相关问题