【问题标题】:How can I optimize query with col IN () and date range?如何使用 col IN () 和日期范围优化查询?
【发布时间】:2021-06-01 17:04:38
【问题描述】:

表结构如下。

CREATE TABLE `log` (
    `id` BIGINT(20) NOT NULL,
    `name` VARCHAR(66) NULL DEFAULT NULL,
    `insert_date` DATETIME(6) NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    INDEX `name` (`name`),
    INDEX `insert_date` (`insert_date`)
);

原查询如下。

SELECT *
FROM log AS irl
WHERE irl.name IN (
    'abc', 'bcd', 'etc' .... 
/* Less than 10,000 and can be imported from other tables using subqueries. */ 
)
AND irl.insert_date >= @START_DATE
AND irl.insert_date <= @END_DATE;

日志表的行数至少为1000万,可以以十亿为单位。

原来的查询太慢了。

如果有好的方法,请介绍一下。

【问题讨论】:

  • 写一个存储过程。首先将 agent_key 插入到虚拟表中,然后使用该表重写查询。
  • @yusufhayırsever 抱歉,这是一种类型。我只是重写了它
  • “使用子查询从其他表导入” - 将两个查询合并在一起可能会更快。
  • read this 然后edit 向我们提供更多信息,以便我们为您提供帮助。

标签: mysql datetime mariadb query-optimization


【解决方案1】:

尝试两种不同的复合索引,一个接一个。

CREATE INDEX firstOneToTry ON log (name, insert_date);

然后

CREATE INDEX secondOneToTry ON log (insert_date, name);

如果您的查询说

WHERE irl.name = 'abc' 
  AND irl.insert_date >= @START_DATE
  AND irl.insert_date <= @END_DATE

我建议的第一个索引显然是正确的选择。但是,由于您选择了多个 name 值,所以不太清楚。

而且,您的日期过滤器中存在错误。考虑使用这个,&lt; 作为日期范围的结尾。否则,您将不会在 @END_DATE 午夜之后获得任何行。

  AND irl.insert_date >= DATE(@START_DATE)
  AND irl.insert_date <  DATE(@END_DATE) + INTERVAL 1 DAY

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    • 2023-01-28
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 2022-01-16
    • 1970-01-01
    相关资源
    最近更新 更多