我有一个包含 2 196 998 条记录的表:
CREATE TABLE price (
dt TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
marketId INT,
buy DOUBLE,
sell DOUBLE,
PRIMARY KEY (dt, marketId),
FOREIGN KEY fk_price_market(marketId) REFERENCES market(id) ON UPDATE CASCADE ON DELETE CASCADE
) ENGINE=INNODB;
查询
select max(buy) from price;
需要 1.92 秒,这是一个合理的时间,如果我在“购买”列上创建索引,则需要 0.00 秒:
CREATE INDEX idx_price_buy ON price (buy);
和查询
select count(*) from price where marketId=309;
需要 0.05 秒并返回 160 570。
但是查询
select max(buy) from price where marketId=309;
即使我创建两个 idice 也需要 15.49 秒(这是非常大的):
CREATE INDEX idx_price_market ON price (marketId);
CREATE INDEX idx_price_buy ON price (buy);
(我不确定,但可能索引 idx_price_market
已经存在,因为外键约束中需要 marketId
列)
1)有什么办法可以优化吗?
2)如果没有,其他数据库呢?他们表现更好吗?
编辑 1:
创建复合索引后
在价格上创建索引 idx_price_market_buy (marketId, buy);
查询需要 0.00 秒。
desc select max(buy) from price where marketId=309;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
1 row in set, 1 warning (0.01 sec)
最佳答案
select max(buy) from price where marketId=309;
在每一列上创建单独的索引可能不允许 MySQL 优化查询。
对于此查询,您需要(marketId, buy)
上的复合索引。
create index idx_price_market_buy ON price (marketId, buy);
索引中列的顺序很重要:首先查询过滤 marketId
(因此您希望此列在复合索引中的第一个位置),然后它计算最大购买
。
关于MySQL select 查询非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58766925/