检索最接近输入日期的日期

时间:2018-11-14 20:59:08

标签: mysql

我具有以下功能:

DELIMITER $$
DROP FUNCTION IF EXISTS f_prevpricedate;
CREATE FUNCTION f_prevpricedate (id CHAR(8), startdate DATE)
RETURNS DATE

BEGIN

DECLARE prevpricedate DATE;

SELECT MAX(f.p_date) INTO prevpricedate
FROM fp_v2_fp_basic_prices AS f 
WHERE f.fsym_id = id AND f.p_date<startdate;

RETURN prevpricedate; 

END$$

基本上,这只是返回最接近输入日期的日期(以前的日期)。但是,由于表非常大,因此运行非常慢。

任何人都知道如何优化它吗?

1 个答案:

答案 0 :(得分:1)

首先,检查explain select ...的内容。

fp_v2_fp_basic_prices.fsym_idfp_v2_fp_basic_prices.p_date被索引了吗?索引使数据库可以快速匹配和比较行,而不必查看所有行。如果没有索引,则必须比较表中的每一行。

例如...

mysql> select count(*) from foo;                                                                                                                              
+----------+
| count(*) |
+----------+
|        3 |
+----------+

mysql> explain select max(this) from foo where this < 42;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | foo   | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+

这表明查询正在进行全表扫描。它不使用键(索引),查询的类型为ALL,并且认为它必须查看表中的所有3行。

mysql> alter table foo add index foo_this (this);
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> explain select max(this) from foo where this < 42;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+
| 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 |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+

这是在添加索引之后。 Select tables optimized away告诉我们优化器已经知道可以使用索引来优化整个查询。


在您的情况下,您要按fsym_idp_date两列进行搜索。 MySQL在查询中每个表只使用一个索引。因此,即使您在fsym_id上有一个索引,在p_date上有一个索引,它也只会使用一个。为了使此查询的性能很好,您需要在单个索引中同时使用它们。

alter table fp_v2_fp_basic_prices add index(p_date, fsym_id);

这将适用于仅使用p_date的查询以及同时使用p_datefsym_id的查询。因此,您不需要仅p_date上的索引。但这并不涵盖仅使用fsym_id的查询。有关更多详细信息,请参见this answer

另请参阅: