mysql视图查询速度很慢

时间:2016-12-14 22:13:06

标签: mysql

我在MySQL中创建了一个视图

CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `invoice_cad_view` AS select `a`.`operator` AS `operator`,`a`.`flag_needs_reporting` AS `flag_needs_reporting`,`a`.`reported_time` AS `reported_time`,`a`.`reporting_type` AS `reporting_type`,`a`.`fk_company` AS `fk_company`,`a`.`fk_branch` AS `fk_branch`,(((case when (`a`.`payment_type_1_m` = 'cash') then `a`.`payment_type_1` else 0 end) + (case when (`a`.`payment_type_2_m` = 'cash') then `a`.`payment_type_2` else 0 end)) + (case when (`a`.`payment_type_3_m` = 'cash') then `a`.`payment_type_3` else 0 end)) AS `cash`,(((case when (`a`.`payment_type_1_m` = 'debit') then `a`.`payment_type_1` else 0 end) + (case when (`a`.`payment_type_2_m` = 'debit') then `a`.`payment_type_2` else 0 end)) + (case when (`a`.`payment_type_3_m` = 'debit') then `a`.`payment_type_3` else 0 end)) AS `debit`,(((case when (`a`.`payment_type_1_m` = 'credit') then `a`.`payment_type_1` else 0 end) + (case when (`a`.`payment_type_2_m` = 'credit') then `a`.`payment_type_2` else 0 end)) + (case when (`a`.`payment_type_3_m` = 'credit') then `a`.`payment_type_3` else 0 end)) AS `credit`,(((case when (`a`.`payment_type_1_m` = 'other') then `a`.`payment_type_1` else 0 end) + (case when (`a`.`payment_type_2_m` = 'other') then `a`.`payment_type_2` else 0 end)) + (case when (`a`.`payment_type_3_m` = 'other') then `a`.`payment_type_3` else 0 end)) AS `other`,((`a`.`payment_type_1` + `a`.`payment_type_2`) + `a`.`payment_type_3`) AS `total_value`,`a`.`last_updated` AS `last_updated`,`a`.`created_date` AS `created_date`,(((select sum((case when (`invoice_items`.`type` = 'sell') then (`invoice_items`.`unit_price` * `invoice_items`.`quantity`) else (-(`invoice_items`.`unit_price`) * `invoice_items`.`quantity`) end)) from `invoice_items` where ((`invoice_items`.`fk_invoice` = `a`.`id`) and (`invoice_items`.`flag_is_deleted` = 'no'))) + `a`.`service_fee`) + `a`.`service_tax`) AS `subtotal` from `invoice` `a` where (`a`.`flag_is_deleted` = 'no');

它有数千条记录并且执行速度非常慢。我运行的任何查询大约需要50秒。你能帮我找出错误或推荐一种更好的方法来创建视图。

提前致谢

1 个答案:

答案 0 :(得分:1)

首先,我会缩进你的查询,以便我能理解它的结构。我这样做了,现在我有了以下图片

Query after indent

然后我注意到你正在使用相关的子查询 在第36-53行 (见Wikipedia),效率低下。所以我会试试 重写查询以改为使用JOIN。新的查询看起来 像这样

Query after rewrite

最后,我会检查这两个表是否已正确编入索引 在列invoice.id和invoice_items.fk_invoice。

以下是“after.sql”

的代码文本
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER 
VIEW `invoice_cad_view` AS 
select 
    `a`.`operator` AS `operator`
    ,`a`.`flag_needs_reporting` AS `flag_needs_reporting`
    ,`a`.`reported_time` AS `reported_time`
    ,`a`.`reporting_type` AS `reporting_type`
    ,`a`.`fk_company` AS `fk_company`
    ,`a`.`fk_branch` AS `fk_branch`
    ,(((case when 
        (`a`.`payment_type_1_m` = 'cash') then `a`.`payment_type_1` else 0 end) 
        + 
        (case when (`a`.`payment_type_2_m` = 'cash') then `a`.`payment_type_2` else 0 end)
    ) + 
    (case when (`a`.`payment_type_3_m` = 'cash') then `a`.`payment_type_3` else 0 end)
    ) AS `cash`
    ,(((case when (`a`.`payment_type_1_m` = 'debit') then `a`.`payment_type_1` else 0 end) 
        + (case when (`a`.`payment_type_2_m` = 'debit') then `a`.`payment_type_2` else 0 end)
    ) + 
    (case when (`a`.`payment_type_3_m` = 'debit') then `a`.`payment_type_3` else 0 end)) AS `debit`
    ,(((case when (`a`.`payment_type_1_m` = 'credit') then `a`.`payment_type_1` else 0 end) 
        + 
    (case when (`a`.`payment_type_2_m` = 'credit') then `a`.`payment_type_2` else 0 end)
    ) 
    + (case when (`a`.`payment_type_3_m` = 'credit') then `a`.`payment_type_3` else 0 end)
    ) AS `credit`
    ,(((case when (`a`.`payment_type_1_m` = 'other') then `a`.`payment_type_1` else 0 end) 
        + 
    (case when (`a`.`payment_type_2_m` = 'other') then `a`.`payment_type_2` else 0 end)
    ) 
    + (case when (`a`.`payment_type_3_m` = 'other') then `a`.`payment_type_3` else 0 end)
    ) AS `other`
    ,((`a`.`payment_type_1` + `a`.`payment_type_2`) + `a`.`payment_type_3`) AS `total_value`
    ,`a`.`last_updated` AS `last_updated`
    ,`a`.`created_date` AS `created_date`
    ,(((
            sum((case when 
                    (`invoice_items`.`type` = 'sell') then 
                        (`invoice_items`.`unit_price` * `invoice_items`.`quantity`) 
                    else 
                        (-(`invoice_items`.`unit_price`) * `invoice_items`.`quantity`) 
                end)
            ) 
        ) 
        + `a`.`service_fee`
    ) 
    + `a`.`service_tax`
    ) AS `subtotal` 
from 
    `invoice` `a` 
    , `invoice_items`
where 
    (`a`.`flag_is_deleted` = 'no')
    and 
    (`invoice_items`.`fk_invoice` = `a`.`id`) 
    and (`invoice_items`.`flag_is_deleted` = 'no')
    )
group by `a`.id             
;