Получение последней цены от конкретного продукта на MYSQL (быстрее, чем это) - PullRequest
0 голосов
/ 04 мая 2011

Я получаю последнюю цену за конкретный продукт, но производительность действительно снижается, если цена превышает 3 миллиона.

У кого-нибудь есть лучший способ сделать это?Мой сервер забивается этим медленным запросом.

prices.id используется для хранения идентификатора магазина в таблице prices, поэтому я могу присоединиться к нему с stores.id из таблицы stores.

SELECT prices.id, prices.price, prices.timelog, prices.user_id FROM prices
WHERE prices.id IN (SELECT stores.id FROM stores WHERE city = "miami" )
AND prices.product_id = 1
AND prices.timelog IN 
  (SELECT MAX( lastprice.timelog ) 
   FROM prices AS lastprice 
   WHERE lastprice.id = prices.id AND lastprice.product_id = 1)

Ответы [ 3 ]

3 голосов
/ 04 мая 2011

Не видя структуры таблиц, я думаю, вы могли бы сделать:

select * from prices
join stores on stores.id = prices.id
where stores.city = 'miami' and prices.product = 1
 order by timelog DESC LIMIT 1
1 голос
/ 04 мая 2011

3 миллиона цен могут означать, что ваше приложение может извлечь выгоду из некоторой денормализации. (т. е. помечать последнюю цену каким-либо образом, помните: однократная запись, многим чтение часто стоит затрат на медленную запись).

С текущими данными стоит попробовать:

SELECT p1.id, p1.price, p1.timelog, p1.user_id 
FROM prices p1
JOIN stores 
ON stores.id = prices.id
AND stores.city = "miami"
LEFT JOIN prices p2
ON p2.product_id = p1.product_id
AND p2.id = p1.id
AND p2.timelog > p1.timelog
WHERE p1.product_id = 1 AND p2.id IS NULL;

... и еще один более быстрый вариант, который всегда ускользает от меня в это время ночи:)

Имейте в виду, что многое может измениться при правильных индексах для таблиц, поэтому обязательно запустите EXPLAIN для лота.

0 голосов
/ 04 мая 2011

Попробуйте тоже:

SELECT prices.id
     , prices.price
     , prices.timelog
     , prices.user_id

FROM prices
    JOIN
      ( SELECT MAX( timelog ) AS lasttimelog
        FROM prices 
        WHERE product_id = 1
      ) AS lastprice
        ON prices.timelog = lastprice.lasttimelog

WHERE EXISTS
    ( SELECT * 
      FROM stores
      WHERE prices.id = stores.id
        AND stores.city = "miami"
    )
  AND prices.product_id = 1

Я бы предположил, что индекс на (id,product_id,timelog) в products и индекс на id или (city,id) в таблице stores помогут повысить скорость запроса.

Было бы лучше, если бы вы выполняли EXPLAIN для запросов, а также размещали структуру таблиц (поля, индексы, ссылки).

...