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

2wnc66cl  于 2021-06-19  发布在  Mysql
关注(0)|答案(1)|浏览(366)

我有以下功能:

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$$

它基本上只返回与输入日期最近的日期(前一个日期)。但是它运行非常慢,因为table很大。
有人知道如何优化这个吗?

daolsyd0

daolsyd01#

首先,检查什么 explain select ... 说。
fp_v2_fp_basic_prices.fsym_id 以及 fp_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_id 以及 p_date . mysql在查询中每个表只使用一个索引。所以即使你有一个索引 fsym_id 还有一个索引 p_date 它将只使用一个。要使这个查询执行得非常好,您需要在一个索引中同时使用这两个索引。

alter table fp_v2_fp_basic_prices add index(p_date, fsym_id);

这将适用于只使用 p_date 以及使用两者的查询 p_date + fsym_id 一起。所以你不需要索引 p_date . 但它不包括只使用 fsym_id . 有关更多详细信息,请参阅此答案。
另请参见:
https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
https://dev.mysql.com/doc/refman/5.7/en/optimization-indexes.html
http://www.mysqltutorial.org/mysql-index/
https://www.tutorialspoint.com/mysql/mysql-indexes.htm

相关问题