[英]Query is taking too much time
我想就以下查询提出您的想法:
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);
即使在expense_data表中有四个索引,此查询也会花费大量时间:
1- Expense_code.
2- expense_user_id
3- expense_supplier_code
4- expense_payment_transfer_from
我不知道为什么要花这么多时间是因为两次连接,还是因为过多的索引。 你能建议吗?
可能是您的where子句包含逻辑错误。 查看最后一行(last 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的所有记录 ”
为了加快处理速度,您可能希望尝试对加入的列的组合进行合并索引。 该索引可能比您现在拥有的四个单独索引更有用,尽管您仍然可以保留它们。 除了这四个字段之外,您甚至还可以尝试通过将status
和/或expense_data
添加到索引来进行试验。
重新编码以使连接更清晰(并删除大规模连接,如果费用状态是所有表都被连接的话):
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);
您必须将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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.