0
SELECT it.uid,it.Name,COALESCE(sum(i.Qty),0)-COALESCE(sum(s.Qty),0) as stock
FROM items it
left outer join sales_items s on it.uid=s.ItemID
left outer join inventory i on it.uid=i.uid
group by s.ItemID,i.uid,it.UID;

这是我的查询。此查询需要 59 秒。我怎样才能加快这个查询?


我的表 -> 项目

      UID            Item
      5089           JAM100GMXDFRUT
      5090           JAM200GMXDFRUT
      5091           JAM500GMXDFRUT
      5092           JAM800GMXDFRUT

表 -> sales_items

- slno        ItemID         Item              Qty
- 9           5089           JAM100GMXDFRUT    5
- 10          5090           JAM200GMXDFRUT    2
- 11          5091           JAM500GMXDFRUT    1

表 -> 库存

- slno         uid            Itemname          Qty
- 102          5089           JAM100GMXDFRUT    10
- 200          5091           JAM500GMXDFRUT    15
- 205          5092           JAM800GMXDFRUT    20

此表有 6000 多行

4

3 回答 3

0

如果我正在设计这样的东西,我会有一个看起来像这样的查询和模式。记下我的 Idx1 索引。我不了解 MySql,但 Sql Server 将使用这些索引来进行 sum 函数,这称为覆盖查询。

select  Item.ItemID, Item.Name, IsNull(sum(inv.Quantity), 0) - IsNull(sum(s.Quantity), 0) as stock
from    Item
Left Join Inventory inv
On      Item.ItemID = inv.ItemID
Left Join Sales s
On      Item.ItemID = s.ItemID
Group by Item.ItemID, Item.Name

Create Table dbo.Location
(
    LocationID int not null identity constraint LocationPK primary key,
    Name NVarChar(256) not null
)

Create Table dbo.Item
(
    ItemID int not null identity constraint ItemPK primary key,
    Name NVarChar(256) not null
);

Create Table dbo.Inventory
(
    InventoryID int not null identity constraint InventoryPK primary key,
    LocationID int not null constraint InventoryLocationFK references dbo.Location(LocationID),
    ItemID int not null constraint InventoryItemFK references dbo.Item(ItemID), 
    Quantity int not null,
    Constraint AK1 Unique(LocationID, ItemID)
);

Create Index InventoryIDX1 on dbo.Inventory(ItemID, Quantity);

Create Table dbo.Sales
(
    SaleID int not null identity constraint SalesPK primary key,
    ItemID int not null constraint SalesItemFK references dbo.Item(ItemID),
    Quantity int not null
);

Create Index SalesIDX1 on dbo.Sales(ItemID, Quantity);
于 2014-12-28T23:23:58.003 回答
0

在连接列上放置索引

sales_items 商品 ID

库存 uid

于 2014-12-28T09:24:30.147 回答
0

除了表上的索引以优化连接之外,您还可以对 S.ItemID 进行分组,而不是仅使用 IT.UID,因为这是连接基础,并且是查询的主 FROM 表的一部分......如果这是 items 表上的可用索引,请使用它,您就完成了。无需引用 group by 中的 sales_items 或 inventory 列名称。

现在,话虽如此,如果您从 sales_items 和库存中汇总的相同“item id”有多个记录,您将遇到的另一个问题是笛卡尔结果,因为我已经非常简化了一个示例你通过

CREATE TABLE items (
  `uid` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(5) NOT NULL,
  PRIMARY KEY (`uid`)
);

CREATE TABLE sales_items (
  `sid` int(11) NOT NULL AUTO_INCREMENT,
  `itemid` int(11),
  `qty` int(5) NOT NULL,
  PRIMARY KEY (`sid`),
  KEY byItemAndQty (`itemid`,`qty`)
);

CREATE TABLE inventory (
  `iid` int(11) NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL,
  `qty` int(5) NOT NULL,
  PRIMARY KEY (`iid`),
  KEY byItemAndQty (`itemid`,`qty`)
);

insert into items ( uid, name ) values ( 1, 'test' );

INSERT INTO sales_items ( sid, itemid, qty ) VALUES ( 1, 1, 1 );
INSERT INTO sales_items ( sid, itemid, qty ) VALUES ( 2, 1, 2 );

INSERT INTO inventory ( iid, uid, qty ) VALUES ( 1, 1, 13 );
INSERT INTO inventory ( iid, uid, qty ) VALUES ( 2, 1, 35 );

简单 1 项,销售项 2 项记录 1.. 数量 1 和 2,总计 = 3 库存 2 条记录,项目 1.. 数量 13 和 35,总计 38

SELECT 
      it.uid, 
      it.Name, 
      sum(i.Qty) as iQty,
      sum(s.Qty) as sQty,
      COALESCE( sum(i.Qty),0) - COALESCE(sum(s.Qty),0) as stock 
   FROM 
      items it 
         left outer join sales_items s 
            on it.uid = s.ItemID 
         left outer join inventory i 
            on it.uid = i.uid 
   group by 
      it.uid

因此,您可能期望 Stock 的查询结果是

uid  name   iQty   sQty   stock
1    test   48     3      45
but in reality becomes
1    test   96     6      90

现在...请注意我的假设,但请从多个这样的表中查看类似的 sum()s 或 count()s。我假设 ITEMS 表是每个项目的一条记录。
Sales_Items 实际上有比提供的更多的列(例如销售详细信息和可以跟踪的每个日期/销售计数)并且可能包含给定项目 id 的多个销售记录数量(因此与我的示例匹配)。最后,库存表同样可以每个相同项目有多个记录,例如按日期跟踪的进货库存购买,因此每个给定项目 ID 有多个记录(也与我的示例相匹配)。

为了防止这种类型的笛卡尔结果,并且还可以提高速度,我会对每个辅助表进行预聚合并加入到该表中。

SELECT 
      it.uid, 
      it.Name, 
      i.iQty,
      s.sQty,
      COALESCE( i.iQty,0) - COALESCE(s.sQty,0) as stock 
   FROM 
      items it 
         left join ( select itemid, sum( qty ) as SQty
                        from sales_items
                        group by itemid ) s
            on it.uid = s.ItemID 
         left join ( select uid, sum( qty ) as IQty
                        from inventory
                        group by uid ) i
            on it.uid = i.uid 
   group by 
      it.uid

你得到正确的值

uid  name   iQty   sQty   stock
1    test   48     3      45

是的,这仅用于单个项目 ID 来证明这一点,但仍适用于您拥有的尽可能多的库存项目以及某些项目可能(或不存在)存在的相应销售/库存记录。

于 2014-12-29T01:44:15.877 回答