Mysql函数占用的时间太长

Mysql函数占用的时间太长,mysql,Mysql,我有一个名为“item”的表,其中有大约8500行,另一个名为“stock”的表,其中存储了日期和位置方面的项目库存。我有两个位置的库存 库存表结构如下所示: stock_dt date - Stores the Date of Stock, loc_id varchar(3) - Stores the Location of Stock, item_id varchar(6) - Stores the Item Code, item_qty decim

我有一个名为“item”的表,其中有大约8500行,另一个名为“stock”的表,其中存储了日期和位置方面的项目库存。我有两个位置的库存

库存表结构如下所示:

stock_dt date           - Stores the Date of Stock,
loc_id varchar(3)       - Stores the Location of Stock,
item_id varchar(6)      - Stores the Item Code,
item_qty decimal(20,2)  - Stores the Item Stock Quantity,
item_cost decimal(20,2) - Stores the Item Stock Cost Value
无论何时,只要有任何商品从商店或到商店的移动,就会在库存表中插入一行,其中包含特定商品的更新库存数据。目前,Stock表包含大约125000行

现在我有一个函数,它接受两个日期参数adt_from和adt_to,并在两个日期检索每个位置的每个项目的库存,即每个位置项目的开盘和收盘库存,并对库存进行一些其他计算

下面是函数的一部分,它花费了异常长的时间,几乎15分钟

-变量声明

declare cur_item cursor for
select item_id
from   item
order by item_id;

declare cur_loc cursor for
select loc_id
from   location;

declare continue handler for not found set not_found = true;

set not_found = false;

open cur_item;

fetch cur_item into s_item;

read_item:
loop
    if not_found then
        leave read_item;
    end if;

    set d_opng_qty = 0;
    set d_opng_cost = 0;
    set d_cls_qty = 0;
    set d_cls_cost = 0;

    open cur_loc;

    fetch cur_loc into s_loc;

    read_loc:
    loop
        if not_found then
            leave read_loc;
        end if;

        -- For Opening Stock:
        select item_qty,
               item_cost
        into   d_opng_qty,
               d_opng_cost
        from   stock
        where  stock_dt < adt_from
        and    loc_id = s_loc
        and    item_id = s_item
        order by stock_dt desc
        limit 1;

        -- For Closing Stock:
        select item_qty,
               item_cost
        into   d_cls_qty,
               d_cls_cost
        from   stock
        where  stock_dt <= adt_to
        and    loc_id = s_loc
        and    item_id = s_item
        order by stock_dt desc
        limit 1;

        fetch cur_loc into s_loc;
    end loop;

    fetch cur_item into s_item;      
end loop;

库存表根据库存数据、loc id和物料id编制索引

我尝试过启用查询缓存并将查询缓存大小设置为128M,但似乎没有任何改进


我对Stock上的2个查询进行了注释,程序只需几秒钟就完成了其余的执行。有什么建议吗?

我想这里的问题是由订单引起的

假设你有一个关于物品、地点、日期的综合索引,我想你需要

ORDER BY item desc, location desc, date desc
以便搜索从正确的结尾开始,并在点击1次后返回

原因是,即使它将命中一个项的复合索引项、位置、日期,它也将按照项ASC、位置ASC的最重要列隐式顺序遍历索引。因此,它需要扫描整个项目的部分历史,以获得最新的记录


我会试着对ORDER BY进行注释,看看这是否是导致问题的原因。

在这里,分组BY不是比手动循环更合适吗?我还没有详细了解你在做什么,所以我可能错了。您可以尝试单独运行这些语句,并使用EXPLAIN查看查询计划器对它们做了什么。还要记住,单独索引多个列在这里没有多大帮助;你需要一个多列索引来获得全部好处,也许项目、地点、日期将是最好的顺序。它已经是一个关于股票、位置和项目的综合索引。它确实是索引顺序。。。。现在,我将复合索引更改为项目、位置、日期的顺序,这大大改变了响应时间。该功能现在只需几秒钟。谢谢戴夫。。。感谢所有其他人以及您的想法,因为OP有where item=?位置=?在语句中,这对查询计划器来说应该不是问题。我认为更可能的情况是没有综合指数,但我们确实需要看到解释的结果才能确定。@Dave我编辑了我的答案,以便更好地解释它,但我同意-在这个阶段很难说。@Dave-请注意,它是股票dt、loc_id和item_id上的复合键