正确优化MySQL数据的日期范围查询?

6tqwzwtp  于 2023-01-01  发布在  Mysql
关注(0)|答案(2)|浏览(87)

我有一个包含大量数值数据的表,我需要查询该表以获得与特定date_addedname最接近的行。
我的问题是这个数据不是按日期排序的,所以当返回结果时,我需要包含ORDER BY date_added(否则它不会返回正确的行)。由于ORDER BY的条件,目前执行此操作需要90秒。
有什么方法可以进一步优化它吗?我已经索引了date_addedname列,所以我不确定还能做什么。我考虑过创建一个新表,其中的数据按照date_added的顺序重新排序,但这并不实用,因为需要定期添加新条目。
我将数值数据存储为十进制,因为它可能非常小、非常大或两者都有。也许以不同的方式存储此数据会更有效?

hwazgwia

hwazgwia1#

在名称和日期上添加一个复合索引。上面的查询将在不使用文件排序的情况下运行。
查询的另一种方式:

SELECT date_added, data_1, data_2, data_3, data_4, data_5, data_6, data_7, data_8, data_9
FROM numeric_data
WHERE date_added = 
(select min(date_added) from numeric_data where date_added >= '2018-05-03 11:00:00' and name = 'aaa')
and name = 'aaa'
limit 1;

小提琴:http://sqlfiddle.com/#!9/4 e8 d89/1 .

dtcbnfnu

dtcbnfnu2#

您可以使用范围分区:
https://dev.mysql.com/doc/refman/5.7/en/partitioning-range.html
您需要根据您拥有的日期范围来定义分区。

CREATE TABLE `numeric_data` (
 `id` int(255) NOT NULL AUTO_INCREMENT,
 `date_added` datetime NOT NULL,
 `name` varchar(8) COLLATE utf8mb4_unicode_ci NOT NULL,
 `data_1` decimal(30,17) NOT NULL,
 `data_2` decimal(30,17) NOT NULL,
 `data_3` decimal(30,17) NOT NULL,
 `data_4` decimal(30,17) NOT NULL,
 `data_5` decimal(30,17) NOT NULL,
 `data_6` decimal(30,17) NOT NULL,
 `data_7` decimal(30,17) NOT NULL,
 `data_8` decimal(30,17) NOT NULL,
 `data_9` decimal(30,17) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `date_added` (`date_added`),
 KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=60000000 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
      PARTITION BY RANGE( TO_DAYS(date_added) ) (
        PARTITION p1 VALUES LESS THAN (TO_DAYS('2018-01-01')),
        PARTITION p2 VALUES LESS THAN (TO_DAYS('2018-02-01')),
        PARTITION p3 VALUES LESS THAN (TO_DAYS('2018-03-01')),
        PARTITION p4 VALUES LESS THAN (TO_DAYS('2018-04-01')),
        PARTITION future VALUES LESS THAN MAXVALUE
      );

对于下面的查询,将仅使用分区“future”:

SELECT date_added, data_1, data_2, data_3, data_4, data_5, data_6, data_7, data_8, data_9
FROM numeric_data
WHERE date_added >= '2018-05-03 11:00:00'
AND name = 'aaa'
ORDER BY date_added LIMIT 1

相关问题