Как эффективно сгруппировать два столбца и вернуть порядок первой строки каждой группы по time_create? - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть большая таблица, которая использовалась для записи количества товара, он уже упорядочен по time_create.

Теперь я хочу получить последнее количество товара в каждом магазине.

Код:

select SQ.store_id,SQ.product_id, max(SQ.time_create) as last_time, SQ.store_product_quantity_new  
from stockquantitylogs as SQ 
where SQ.time_create > unix_timestamp("2018-08-01")*1000  
group by SQ.store_id, SQ.product_id 

Но это очень, очень медленно.

Поэтому мне интересно, как сделать мой запрос более эффективным.

PS: SQ.store_product_quantity_new добирается до max(SQ.time_create)? Я не уверен в этом, просто хочу получить store_product_quantity_new с max(SQ.time_create)


Структура

create table stockquantitylogs
(
  id                         char(36) collate utf8_bin default '' not null
    primary key,
  store_id                   char(36) collate utf8_bin default '' not null,
  product_id                 char(36) collate utf8_bin default '' not null,
  time_create                bigint                               not null,
  time_update                bigint                               not null,
  store_product_quantity_old int                                  not null,
  store_product_quantity_new int                                  not null
);

create index IX_product_id
  on stockquantitylogs (product_id);

create index IX_store_id
  on stockquantitylogs (store_id);

create index IX_time_create
  on stockquantitylogs (time_create);

create index IX_time_update
  on stockquantitylogs (time_update);

1 Ответ

0 голосов
/ 07 сентября 2018

Вы не можете просто использовать max () для столбца и автоматически выбирать другие столбцы из той же строки. В более поздних версиях MySQL опция ONLY_FULL_GROUP_BY включена по умолчанию, что означает, что даже попытка этого запроса является ошибкой (см. https://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html).

Вам нужно выяснить, какие строки вам нужны, а затем выбрать их:

SELECT sq.store_id, sq.product_id, sq.time_create AS last_time, sq.store_product_quantity_new FROM stockquantitylogs AS sq INNER JOIN ( SELECT store_id, product_id, MAX(time_create) AS time_create FROM stockquantitylogs GROUP BY store_id, product_id ) AS sq_latest USING(store_id, product_id, time_create)

Здесь мы сначала выбираем нужные (последние) строки с помощью:

SELECT store_id, product_id, MAX(time_create) AS time_create FROM stockquantitylogs GROUP BY store_id, product_id

Затем внешний запрос выбирает строки для возврата, соединяясь с соответствующими строками из внутренних результатов.

Чтобы это работало хорошо, вам понадобится индекс для соответствующих строк:

INDEX `store_id_product_id_time_create` (`store_id`, `product_id`, `time_create`)

Обратите внимание, что я удалил ваше утверждение where - если это необходимо, добавьте его во внутренний запрос sq_latest.

...