1

我想了解您对以下查询的想法:

select a.expense_code, a.expense_date, a.expense_supplier_code, b.supplier_name, a.expense_discount, a.expense_payment_method, a.expense_payment_transfer_to, a.expense_advance, a.expense_status,
                            sum(c.expense_item_buy_price * c.expense_item_quantity) , d.account_name, a.expense_counter, a.expense_type, a.expense_saving_type, a.expense_payment_transfer_from
                            from expense_data a, supplier_data b, expense_item c, tree_data d
                            where a.expense_supplier_code = b.supplier_code and a.expense_payment_transfer_to= d.account_code
                            and a.expense_counter = c.expense_counter
                            and a.expense_date between '2013-01-01' and '2014-01-01' and a.expense_status = 0 or a.expense_status = 2 group by (a.expense_counter);

即使在费用数据表中有四个索引,此查询也花费了很多时间:

1- Expense_code. 
2- expense_user_id
3- expense_supplier_code
4- expense_payment_transfer_from

我不知道为什么要花这么多时间,是因为两个人的加入,还是因为太多的indeces。你能建议吗?

4

4 回答 4

2

可能是您的 where 子句包含逻辑错误。查看最后一行(最后一个 OR 条件):

where 
  ....
  and a.expense_counter = c.expense_counter 
  and a.expense_date BETWEEN '2013-01-01' AND '2014-01-01' 
  and a.expense_status = 0 
  or a.expense_status = 2 

这意味着“在日期等之间获取记录,并且状态为 0,或者获取状态为 2 的所有记录

于 2013-07-13T09:50:01.270 回答
0

重新编码以使连接更清晰(并删除如果费用状态是所有表都已连接的大量连接)给出: -

SELECT a.expense_code, 
    a.expense_date, 
    a.expense_supplier_code, 
    b.supplier_name, 
    a.expense_discount, 
    a.expense_payment_method, 
    a.expense_payment_transfer_to, 
    a.expense_advance, 
    a.expense_status,
    SUM(c.expense_item_buy_price * c.expense_item_quantity) , 
    d.account_name, 
    a.expense_counter, 
    a.expense_type, 
    a.expense_saving_type, 
    a.expense_payment_transfer_from
FROM expense_data a, 
INNER JOIN supplier_data b ON a.expense_supplier_code = b.supplier_code
INNER JOIN expense_item c ON a.expense_counter = c.expense_counter
INNER JOIN tree_data d ON a.expense_payment_transfer_to= d.account_code
WHERE a.expense_date BETWEEN '2013-01-01' AND '2014-01-01' 
AND a.expense_status = 0 OR a.expense_status = 2 
GROUP BY (a.expense_counter);

考虑到这一点,您必须在supplier_data 表上的supplier_code 上有一个索引,在expense_item 表上的expense_counter 上有一个索引,在tree_data 表上的account_code 上有一个索引。

我怀疑您真的不想退回费用状态为 0 且费用日期在该范围内的项目,无论日期如何,费用状态为 2 的任何记录都可能是您想要的:-

SELECT a.expense_code, 
    a.expense_date, 
    a.expense_supplier_code, 
    b.supplier_name, 
    a.expense_discount, 
    a.expense_payment_method, 
    a.expense_payment_transfer_to, 
    a.expense_advance, 
    a.expense_status,
    SUM(c.expense_item_buy_price * c.expense_item_quantity) , 
    d.account_name, 
    a.expense_counter, 
    a.expense_type, 
    a.expense_saving_type, 
    a.expense_payment_transfer_from
FROM expense_data a, 
INNER JOIN supplier_data b ON a.expense_supplier_code = b.supplier_code
INNER JOIN expense_item c ON a.expense_counter = c.expense_counter
INNER JOIN tree_data d ON a.expense_payment_transfer_to= d.account_code
WHERE a.expense_date BETWEEN '2013-01-01' AND '2014-01-01' 
AND a.expense_status IN (0, 2)
GROUP BY (a.expense_counter);
于 2013-07-13T13:36:38.890 回答
0

为了加快速度,您可能希望尝试在您加入的列的组合上创建组合索引。该索引可能比您现在拥有的四个独立索引更有用,尽管您仍然可以保留它们。除了这四个字段之外,您甚至可能想通过添加status和/或expense_data到索引来进行试验。

于 2013-07-13T09:42:47.677 回答
-1

您必须将 OR 条件放在括号中:

SELECT a.expense_code, 
   a.expense_date, 
   a.expense_supplier_code, 
   b.supplier_name, 
   a.expense_discount, 
   a.expense_payment_method, 
   a.expense_payment_transfer_to, 
   a.expense_advance, 
   a.expense_status, 
   SUM(c.expense_item_buy_price * c.expense_item_quantity), 
   d.account_name, 
   a.expense_counter, 
   a.expense_type, 
   a.expense_saving_type, 
   a.expense_payment_transfer_from 
FROM expense_data a, 
   supplier_data b, 
   expense_item c, 
   tree_data d 
WHERE a.expense_supplier_code = b.supplier_code 
   AND a.expense_payment_transfer_to = d.account_code 
   AND a.expense_counter = c.expense_counter 
   AND a.expense_date BETWEEN '2013-01-01' AND '2014-01-01' 
   AND (a.expense_status = 0 OR a.expense_status = 2)
GROUP BY a.expense_counter; 
于 2013-07-13T09:42:40.947 回答