我想就下面的问题采取您的想法:
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
我不知道为什么需要这么多时间因为两次加入或是因为太多的不足。你能建议吗?
答案 0 :(得分: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的所有记录”
答案 1 :(得分:0)
为了加快速度,您可能希望尝试在您加入的列的组合上创建组合索引。该索引可能比您现在拥有的四个独立索引更有用,尽管您仍然可以保留这些索引。除了这四个字段之外,您甚至可以通过向索引添加status
和/或expense_data
进行试验。
答案 2 :(得分: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);
答案 3 :(得分:-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;