开发者

Finding data closest to date?

I have a table

CREATE TABLE `symbol_details` (
  `symbol_header_id` int(11) DEFAULT NULL,
  `DATE` datetime DEFAULT NULL,
  `ADJ_NAV` double DEFAULT NULL
)

with ~20,000,000 entries. Now I want to find the ADJ_NAV value closest to the end of th开发者_如何学运维e quarter for just one symbol_header_id:

SET @quarterend = '2009-3-31';

SELECT  symbol_header_id AS she, ADJ_NAV AS aend FROM symbol_details
WHERE
 symbol_header_id = 18546 
 AND DATE= (
# date closest after quarter end
SELECT DATE FROM symbol_details
WHERE ABS(DATEDIFF(DATE, @quarterend)) < 10
AND DATE<=@quarterend
AND symbol_header_id = 18546 
ORDER BY  ABS(DATEDIFF(DATE, @quarterend)) ASC LIMIT 1)

When I run the inner "select date" query it returns quickly. Just running the outer query with the correct date filled in instead of the subquery also finishes very quick. But when I run the whole thing it takes forever - something is wrong?


Seems that the optimizer has some problems to properly evaluate the statement and find the most efficient plan. (In Oracle, I'd ask you to update the statistics, but I'm not sure how the optimizer works in MySQL.)

I'd try some other ways of expressing your statement to see what makes most sense to the optimizer:

  • explicitly connect the two symbol_header_ids of the immer and the outer query
  • try a SELECT max(date) .. instead of the 'Order By Limit 1'
  • try to do a self join of symbol_details

Hope there is a useful idea in here.


You can probably do without the subquery. Just grab the first row:

SELECT *
FROM symbol_details
WHERE DATE <= @quarterend
AND symbol_header_id = 18546
ORDER BY DATE DESC
LIMIT 1


Try:

   SELECT t.symbol_header_id,
          COALESCE(t.adj_nav, '0.0') 'adj_nav'
     FROM SYMBOL_DETAILS t
LEFT JOIN (SELECT sh.symbol_header_id,
                  MAX(sh.date) 'max_date'
             FROM SYMBOL_DETAILS sh
            WHERE ABS(DATEDIFF(sh.date, @quarter_end)) < 10
              AND sh.date <= @quarter_end) x ON x.symbol_header_id = t.symbol_header_id
                                            AND x.max_date = t.date
   WHERE t.symbol_header_id = 18546
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜