0

我有一张桌子

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

有约 20,000,000 个条目。现在我想为一个 symbol_header_id 找到最接近季度末的 ADJ_NAV 值:

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)

当我运行内部“选择日期”查询时,它会快速返回。只需运行带有正确日期而不是子查询的外部查询也可以很快完成。但是当我运行整个过程时,它需要永远 - 有什么问题吗?

4

3 回答 3

2

似乎优化器在正确评估语句并找到最有效的计划方面存在一些问题。(在 Oracle 中,我会要求您更新统计信息,但我不确定优化器在 MySQL 中是如何工作的。)

我会尝试一些其他方式来表达你的陈述,看看什么对优化器最有意义:

  • 显式连接 immer 和外部查询的两个 symbol_header_id
  • 尝试 aSELECT max(date) ..而不是 'Order By Limit 1'
  • 尝试对 symbol_details 进行自连接

希望这里有一个有用的想法。

于 2009-11-22T18:01:57.830 回答
1

您可能可以不使用子查询。只需抓住第一行:

SELECT *
FROM symbol_details
WHERE DATE <= @quarterend
AND symbol_header_id = 18546
ORDER BY DATE DESC
LIMIT 1
于 2009-11-22T17:57:40.197 回答
1

尝试:

   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
于 2009-11-22T18:25:22.907 回答