【问题标题】:MariaDB query optimizationMariaDB 查询优化
【发布时间】:2021-04-06 06:12:05
【问题描述】:

是否有任何选项可以优化此查询。它已经运行了将近 4 个小时,我仍然没有结果。表的当前行数为 282359

select c.id
from capacity_log c
where c.id = (
    select c1.id
    from capacity_log c1
     where  
        c1.date_occurred < '2020-10-1' 
        and c1.aux2 is null
        and c1.order_product_id = c.order_product_id
        and yearweek(c1.date_occurred) = yearweek(c.date_occurred)
    order by c1.used_capacity desc limit 1
)

想法是为每个order_product_id获取每周最大使用容量列的id

CREATE TABLE `capacity_log` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`date_occurred` DATETIME NOT NULL,
`ip_address` VARCHAR(255) NOT NULL DEFAULT '',
`order_product_id` INT UNSIGNED NOT NULL,
`serial` VARCHAR(255) NOT NULL DEFAULT '',
`used_capacity` BIGINT NULL DEFAULT NULL,
`aux2` INT NULL DEFAULT NULL,
`request` BLOB NULL,
`retry_count` INT NOT NULL DEFAULT '0',
`fetch_time` INT NOT NULL DEFAULT '0',
`response` BLOB NULL,
`custom_fetch_time` INT NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
INDEX `user_id` (`order_product_id`))




    +------+--------------------+-------+------+---------------+---------+---------+--------------------------------+--------+-----------------------------+
    | id   | select_type        | table | type | possible_keys | key     | key_len | ref                            | rows   | Extra                       |
    +------+--------------------+-------+------+---------------+---------+---------+--------------------------------+--------+-----------------------------+
    |    1 | PRIMARY            | c     | ALL  | NULL          | NULL    | NULL    | NULL                           | 390573 | Using where                 |
    |    2 | DEPENDENT SUBQUERY | c1    | ref  | user_id       | user_id | 4       | web_license.c.order_product_id |    134 | Using where; Using filesort |
    +------+--------------------+-------+------+---------------+---------+---------+--------------------------------+--------+-----------------------------+

版本:10.1.47-MariaDB-0+deb9u1

【问题讨论】:

  • 嗨,欢迎来到 Stack Overflow。我们很高兴你在这里。我有意见。当您询问有关查询优化的问题时,您应该包括表的定义,这样我们就不必猜测索引或数据类型。在 mysql 客户端中运行 SHOW CREATE TABLE capacity_log,并将结果包含在您的问题中。还可以使用EXPLAIN 报告查询的当前优化策略,并将其包括在内。请将这些作为文本发布,而不是屏幕截图。最后,包括SELECT @@version; 的结果,因为最佳答案可能取决于最新版本的 MySQL 的功能。
  • 我在your previous question 的回复中提出了优化建议,你试过了吗?
  • 您使用的是 MariaDB 10.1,但要执行您想要的查询,您应该使用 window functions,这在 MariaDB 10.2 中受支持。建议你升级。另外,MariaDB 10.1 is now past its end of life,所以无论如何你都应该升级。
  • 您建议的选项返回的结果与“未优化选项”@GMB 不同
  • @ПламенЦанов:这太令人惊讶了。您能否提供一个 db fiddle 来证明该问题(最好作为对另一个问题的评论)?

标签: mariadb query-optimization greatest-n-per-group


【解决方案1】:

使用窗口函数,需要升级到 MariaDB 10.2 或更高版本:

select t.id
from (
    select id, row_number() over (partition by order_product_id,
        yearweek(date_occurred) order by used_capacity desc) as rownum
    from capacity_log
    where date_occurred < '2020-10-1'
    and aux2 is null
) as t
where t.rownum = 1;

我认为以下索引将有助于此查询:

alter table capacity_log add index (aux2, date_occurred, order_product_id, used_capacity);

但我不使用 MariaDB,所以我没有测试过这个。

【讨论】:

    猜你喜欢
    • 2018-02-07
    • 2016-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 2019-01-01
    • 2018-07-24
    • 1970-01-01
    相关资源
    最近更新 更多