MySQL select-запрос ужасно медленный - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть таблица с 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;

занимает 15,49 с (это очень много), даже если я создаю оба идентификатора:

CREATE INDEX idx_price_market ON price (marketId);
CREATE INDEX idx_price_buy ON price (buy);

(я не уверен, но, вероятно, индекс idx_price_market уже существует, поскольку необходим столбец marketIdв ограничении внешнего ключа)

1) Есть ли способ его оптимизации?

2) Если нет, то как насчет других баз данных? Они работают лучше?

EDIT1:

После создания составного индекса

CREATE INDEX idx_price_market_buy ON цена (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)

1 Ответ

6 голосов
/ 08 ноября 2019
select max(buy) from price where marketId=309;

Создание отдельных индексов для каждого столбца, вероятно, не позволяет MySQL оптимизировать запрос.

Для этого запроса требуется составной индекс для (marketId, buy).

create index idx_price_market_buy ON price (marketId, buy);

Порядок столбцов в индексе имеет значение: сначала фильтры запросов на marketId (поэтому вы хотите, чтобы этот столбец занимал первую позицию в индексе слияния), , затем , он вычисляетмаксимум buy.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...