2016-12-15 28 views
-1

我已经在MySQLMySQL视图的查询需要很长加载

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` 
SQL SECURITY DEFINER VIEW `inventory_view` AS 
select (case when isnull(`a`.`items_sold`) then 0 else `a`.`items_sold` end) AS `sold_qty`, 
     (case when isnull(`a`.`items_bought`) then 0 else `a`.`items_bought` end) AS `bought_qty`, 
     (case when isnull(`a`.`credit`) then 0 else `a`.`credit` end) AS `credit_amount`, 
     (case when isnull(`a`.`debit`) then 0 else `a`.`debit` end) AS `debit_amount`, 
     (case when isnull(`tv`.`count`) then 0 else `tv`.`count` end) AS `tranfers`, 
     (case when isnull(`a`.`inhand`) then 0 else `a`.`inhand` end) AS `balance`, 
     (case when isnull(`tv`.`count`) then `a`.`inhand` when isnull(`a`.`inhand`) then `tv`.`count` else (`a`.`inhand` + `tv`.`count`) end) AS `in_hand`, 
     (case when isnull(`a`.`company_id`) then `tv`.`fk_company` else `a`.`company_id` end) AS `company`, 
     (case when isnull(`a`.`branch_id`) then `tv`.`fk_branch` else `a`.`branch_id` end) AS `branch`, 
     (case when isnull(`a`.`item_code`) then convert(`tv`.`fk_item_code` using utf8) else convert(`a`.`item_code` using utf8) end) AS `item`, 
     (case when isnull(`a`.`operator`) then `tv`.`user` else `a`.`operator` end) AS `fk_operator` 
from (`transfer_view` `tv` left join `inventory_main` `a` on(((convert(`tv`.`fk_item_code` using utf8) = convert(`a`.`item_code` using utf8)) and (`a`.`operator` = `tv`.`user`)))) 
union 
select (case when isnull(`a`.`items_sold`) then 0 else `a`.`items_sold` end) AS `sold_qty`, 
     (case when isnull(`a`.`items_bought`) then 0 else `a`.`items_bought` end) AS `bought_qty`, 
     (case when isnull(`a`.`credit`) then 0 else `a`.`credit` end) AS `credit_amount`, 
     (case when isnull(`a`.`debit`) then 0 else `a`.`debit` end) AS `debit_amount`, 
     (case when isnull(`tv`.`count`) then 0 else `tv`.`count` end) AS `tranfers`, 
     (case when isnull(`a`.`inhand`) then 0 else `a`.`inhand` end) AS `balance`, 
     (case when isnull(`tv`.`count`) then `a`.`inhand` when isnull(`a`.`inhand`) then `tv`.`count` else (`a`.`inhand` + `tv`.`count`) end) AS `in_hand`, 
     (case when isnull(`a`.`company_id`) then `tv`.`fk_company` else `a`.`company_id` end) AS `company`, 
     (case when isnull(`a`.`branch_id`) then `tv`.`fk_branch` else `a`.`branch_id` end) AS `branch`, 
     (case when isnull(`a`.`item_code`) then convert(`tv`.`fk_item_code` using utf8) else convert(`a`.`item_code` using utf8) end) AS `item`, 
     (case when isnull(`a`.`operator`) then `tv`.`user` else `a`.`operator` end) AS `fk_operator` 
from (`inventory_main` `a` left join `transfer_view` `tv` on(((convert(`tv`.`fk_item_code` using utf8) = convert(`a`.`item_code` using utf8)) and (`a`.`operator` = `tv`.`user`)))); 

它有上千条记录,并执行很慢创建的视图。我运行的任何查询大约需要50秒。

你能帮我找到错误还是建议一个更好的方法来创建视图?

+3

不要将整件事发布在一行上。添加换行符并缩进它,以便我们可以看到它在做什么。 – Barmar

+1

查询本身并没有告诉我们任何事情。请包括select的解释结果以及受影响表中所有索引和索引列的列表。您还需要告诉我们您希望从报告中获得什么(样本数据和基于样本数据的预期输出会有很大的帮助)。 – Shadow

+0

视图有什么作用?这个查询的目的是什么?你需要指定你需要帮助的方式,以便人们能够理解你,而不是有你的观点。我们在你的生活中并不是无所不知的。 – 2016-12-15 19:10:08

回答

0

在transfer_view的fk_item_code和user上创建一个复合索引。

在inventory_main的item_code和operator上创建一个复合索引。

尝试切换您的一些语句的使用​​3210这样的:

create view inventory_view as 

select 
     coalesce(a.items_sold, 0) as sold_qty, 
     coalesce(a.items_bought, 0) as bought_qty, 
     coalesce(a.credit, 0) as credit_amount, 
     coalesce(a.debit, 0) as debit_amount, 
     coalesce(tv.count, 0) as transfers, 
     coalesce(a.inhand, 0) as balance, 
     coalesce(tv.count, 0) + coalesce(a.inhand, 0) as in_hand, 
     coalesce(a.company_id, tv.fk_company) as company, 
     coalesce(a.branch_id, tv.fk_branch) as branch, 
     convert(coalesce(a.item_code, tv.fk_item_code) using utf8) as item, 
     coalesce(a.operator, tv.user) as fk_operator 
from transfer_view tv 
left join inventory_main a 
     on convert(tv.fk_item_code using utf8) = convert(a.item_code using utf8) 
     and a.operator = tv.user 

union 

select 
     coalesce(a.items_sold, 0) as sold_qty, 
     coalesce(a.items_bought, 0) as bought_qty, 
     coalesce(a.credit, 0) as credit_amount, 
     coalesce(a.debit, 0) as debit_amount, 
     coalesce(tv.count, 0) as transfers, 
     coalesce(a.inhand, 0) as balance, 
     coalesce(tv.count, 0) + coalesce(a.inhand, 0) as in_hand, 
     coalesce(a.company_id, tv.fk_company) as company, 
     coalesce(a.branch_id, tv.fk_branch) as branch, 
     convert(coalesce(a.item_code, tv.fk_item_code) using utf8) as item, 
     coalesce(a.operator, tv.user) as fk_operator 
from inventory_main a 
left join transfer_view tv 
     on convert(tv.fk_item_code using utf8) = convert(a.item_code using utf8) 
     and a.operator = tv.user; 

这是否提高查询的性能?

如果不是,这里是我建议的步骤如下:

  • 两个表
  • 之间找到transfer_view的所有记录在inventory_main没有符合条件的记录
  • 从inventory_main没有找到的所有记录找到匹配的记录在transfer_view匹配记录
  • union all的三个数据集

示例 -

create view inventory_view as 

select 
    ... 
from transfer_view tv 
inner join inventory_main a 
    on tv.fk_item_code = a.item_code -- you can convert ONLY if you need 
    and a.operator = tv.user 

union all 

select 
    ... 
from transfer_view tv 
where not exists (
    select 1 from inventory_main 
    where item_code = tv.fk_item_code and operator = tv.user 
) 

union all 

select 
    ... 
from inventory_main a 
where not exists (
    select 1 from transfer_view 
    where fk_item_code = a.item_code and user = a.operator 
);