我在MySQL中创建了一个视图
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秒。
您能否帮我找出错误或建议更好的方法来创建视图?
答案 0 :(得分:0)
在transfer_view的fk_item_code和user上创建一个复合索引。
在inventory_main的item_code和operator上创建一个复合索引。
尝试将您的部分语句切换为使用coalesce
,如下所示:
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;
这会改善查询的效果吗?
如果没有,以下是我推荐的步骤:
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
);