0

我试图优化这个存储过程。目前,从链条的顶端完成此次迭代可能需要约2.4-2.7秒。如果可能的话,我很乐意将其降至1秒以下。改善此存储过程的性能在MySQL

我已经在我能做些什么来优化这个最MySQL的自己的秘诀,不工作做了研究。您无法使用LOCK表或在存储过程中使用LOAD DATA语句。运行测试时,看起来INSERT INTO SELECT语句在这个查询中占用了大部分时间。

当我跑了一个电话,我得到了2.6秒周围13 INSERT INTO陈述发射了。至少有3个人花了0.43-0.45秒完成。所有其他陈述花费很少时间来完成。

这是我当前的设置我的 '的my.cnf' 文件中:

default-storage-engine = MyISAM 
key_buffer_size = 256M 
innodb_buffer_pool_size = 3G 
innodb_buffer_pool_load_at_startup = ON 
innodb_sort_buffer_size = 16M 
innodb_flush_method = O_DIRECT 
read_buffer_size = 4M 
thread_stack = 256K 
bulk_insert_buffer_size = 64MB 

这里是我的存储过程:

BEGIN 
    DECLARE lastLayer INT; 
    DECLARE lastInsertCount INT; 
    DECLARE tempTableRowCount INT; 
    DROP TABLE IF EXISTS `temp`; 
    DROP TABLE IF EXISTS `pendingBusiness`; 


    CREATE TABLE `temp` 
    (
     `layer` INT(5), 
     `title_c` VARCHAR(255), 
     `name` VARCHAR(255), 
     `rep_first_name` VARCHAR(255), 
     `rep_last_name` VARCHAR(255), 
     `id_c` CHAR(36), 
     `contact_status_reps_c` VARCHAR(255), 
     `phone_mobile` VARCHAR(255), 
     `contract_type_c` VARCHAR(255), 
     `email_address` VARCHAR(255) 
    ); 


    CREATE TABLE `pendingBusiness` 
    (
     `layer` INT(5), 
     `title_c` VARCHAR(255), 
     `name` VARCHAR(255), 
     `rep_first_name` VARCHAR(255), 
     `rep_last_name` VARCHAR(255), 
     `id_c` CHAR(36), 
     `contact_status_reps_c` VARCHAR(255), 
     `investor_first_name` VARCHAR(255), 
     `investor_last_name` VARCHAR(255), 
     `product_detail` VARCHAR(255), 
     `paperwork_status_c` VARCHAR(255), 
     `next_step` VARCHAR(255), 
     `outstanding_requirements_c` VARCHAR(255), 
     `funding_status_c` VARCHAR(255), 
     `funding_next_step_c` VARCHAR(255), 
     `fulfillment_status_c` VARCHAR(255), 
     `fulfillment_next_step_c` VARCHAR(255), 
     `amount` VARCHAR(255), 
     `stage` VARCHAR(255), 
     `date_entered` DATETIME, 
     `case_manager` VARCHAR(255), 
     `lost_sale_date_c` DATETIME, 
     `compensation_run_c` DATETIME, 
     `product_id` CHAR(36), 
     `rep_state` VARCHAR(255), 
     `investor_state` VARCHAR(255) 
    ); 

    INSERT INTO `temp`(`layer`, `title_c`, `name`, `rep_first_name`, `rep_last_name`, `id_c`, `contact_status_reps_c`, `phone_mobile`,`contract_type_c`,`email_address`) 
    SELECT 0, 
    wn_writing_number_cstm.title_c, 
    wn_writing_number.`name`, 
    preps_contracted_reps.first_name, 
    preps_contracted_reps.last_name, 
    wn_writing_number_cstm.id_c, 
    preps_contracted_reps_cstm.contact_status_reps_c, 
    preps_contracted_reps.phone_mobile, 
    preps_contracted_reps_cstm.contract_type_c, 
    email_addresses.email_address 
FROM wn_writing_number LEFT OUTER JOIN wn_writing_number_cac_customize_agent_comp_1_c ON wn_writing_number_cac_customize_agent_comp_1_c.wn_writing946b_number_ida = wn_writing_number.id 
    LEFT OUTER JOIN cac_customize_agent_comp ON wn_writing_number_cac_customize_agent_comp_1_c.wn_writing3148nt_comp_idb = cac_customize_agent_comp.id 
    LEFT OUTER JOIN cac_customize_agent_comp_cstm ON cac_customize_agent_comp.id = cac_customize_agent_comp_cstm.id_c 
    LEFT OUTER JOIN aos_products_cac_customize_agent_comp_1_c ON cac_customize_agent_comp_cstm.id_c = aos_products_cac_customize_agent_comp_1_c.aos_produca2b8nt_comp_idb 
    LEFT OUTER JOIN preps_contracted_reps_wn_writing_number_1_c ON preps_contracted_reps_wn_writing_number_1_c.preps_contracted_reps_wn_writing_number_1wn_writing_number_idb = wn_writing_number.id 
    LEFT OUTER JOIN preps_contracted_reps ON preps_contracted_reps_wn_writing_number_1_c.preps_cont9effed_reps_ida = preps_contracted_reps.id 
    LEFT OUTER JOIN preps_contracted_reps_cstm ON preps_contracted_reps.id = preps_contracted_reps_cstm.id_c 
    LEFT OUTER JOIN email_addr_bean_rel ON email_addr_bean_rel.bean_id = preps_contracted_reps_cstm.id_c 
    LEFT OUTER JOIN email_addresses ON email_addr_bean_rel.email_address_id = email_addresses.id 
    LEFT OUTER JOIN wn_writing_number_cstm ON wn_writing_number_cstm.id_c = wn_writing_number.id 
    WHERE wn_writing_number_cstm.wn_writing_number_id_c = passId AND wn_writing_number.deleted = '0' AND preps_contracted_reps.deleted = '0' AND wn_writing_number.deleted = '0' AND email_addr_bean_rel.deleted = '0' 
    GROUP BY wn_writing_number.`name`; 

    INSERT INTO `pendingBusiness`(`title_c`, `name`, `rep_first_name`, `rep_last_name`, `id_c`, `contact_status_reps_c`, `investor_first_name`, `investor_last_name`, `product_detail`, `paperwork_status_c`, `next_step`, `outstanding_requirements_c`, `funding_status_c`, `funding_next_step_c`, `fulfillment_status_c`, `fulfillment_next_step_c`, `amount`, `stage`, `date_entered`, `case_manager`, `lost_sale_date_c`, `compensation_run_c`, `product_id`, `rep_state`, `investor_state`) 
    SELECT 
    wn_writing_number_cstm.title_c, 
    wn_writing_number.`name`, 
    preps_contracted_reps.first_name, 
    preps_contracted_reps.last_name, 
    wn_writing_number_cstm.id_c, 
    preps_contracted_reps_cstm.contact_status_reps_c, 
    contacts.first_name, 
    contacts.last_name, 
    aos_products.`name`, 
    opportunities_cstm.paperwork_status_c, 
    opportunities.next_step, 
    opportunities_cstm.outstanding_requirements_c, 
    opportunities_cstm.funding_status_c, 
    opportunities_cstm.funding_next_step_c, 
    opportunities_cstm.fulfillment_status_c, 
    opportunities_cstm.fulfillment_next_step_c, 
    opportunities.amount, 
    opportunities_cstm.stage_c, 
    opportunities.date_entered, 
    CONCAT(users.first_name, " ", users.last_name) AS case_manager, 
    opportunities_cstm.lost_sale_date_c, 
    opportunities_cstm.compensation_run_c, 
    aos_products.id, 
    preps_contracted_reps.primary_address_state, 
    opportunities_cstm.state_of_residence_c 
FROM wn_writing_number 
    LEFT OUTER JOIN preps_contracted_reps_wn_writing_number_1_c ON preps_contracted_reps_wn_writing_number_1_c.preps_contracted_reps_wn_writing_number_1wn_writing_number_idb = wn_writing_number.id 
    LEFT OUTER JOIN preps_contracted_reps ON preps_contracted_reps_wn_writing_number_1_c.preps_cont9effed_reps_ida = preps_contracted_reps.id 
    LEFT OUTER JOIN preps_contracted_reps_cstm ON preps_contracted_reps.id = preps_contracted_reps_cstm.id_c 
    LEFT OUTER JOIN wn_writing_number_cstm ON wn_writing_number_cstm.id_c = wn_writing_number.id 
    LEFT OUTER JOIN opportunities_cstm ON opportunities_cstm.wn_writing_number_id_c = wn_writing_number.id 
    LEFT OUTER JOIN contacts ON opportunities_cstm.contact_id_c = contacts.id 
    LEFT OUTER JOIN opportunities ON opportunities_cstm.id_c = opportunities.id 
    LEFT OUTER JOIN aos_products ON opportunities_cstm.aos_products_id_c = aos_products.id 
    LEFT OUTER JOIN users ON opportunities_cstm.user_id_c = users.id 
WHERE wn_writing_number.id = passId AND opportunities.deleted = '0' AND opportunities.date_entered >= DATE_SUB(NOW(),INTERVAL 1.5 YEAR) 
GROUP BY opportunities_cstm.id_c; 

    SET lastLayer := 0; 
    SET lastInsertCount := 1; 

    LayerLoop: WHILE lastInsertCount > 0 DO 
     INSERT INTO `temp`(`layer`, `title_c`, `name`, `rep_first_name`, `rep_last_name`, `id_c`, `contact_status_reps_c`, `phone_mobile`,`contract_type_c`,`email_address`) 
     SELECT lastLayer + 1, 
     wn_writing_number_cstm.title_c, 
     wn_writing_number.`name`, 
     preps_contracted_reps.first_name, 
     preps_contracted_reps.last_name, 
     wn_writing_number_cstm.id_c, 
     preps_contracted_reps_cstm.contact_status_reps_c, 
     preps_contracted_reps.phone_mobile, 
     preps_contracted_reps_cstm.contract_type_c, 
     email_addresses.email_address 
    FROM wn_writing_number LEFT OUTER JOIN wn_writing_number_cac_customize_agent_comp_1_c ON wn_writing_number_cac_customize_agent_comp_1_c.wn_writing946b_number_ida = wn_writing_number.id 
     LEFT OUTER JOIN cac_customize_agent_comp ON wn_writing_number_cac_customize_agent_comp_1_c.wn_writing3148nt_comp_idb = cac_customize_agent_comp.id 
     LEFT OUTER JOIN cac_customize_agent_comp_cstm ON cac_customize_agent_comp.id = cac_customize_agent_comp_cstm.id_c 
     LEFT OUTER JOIN aos_products_cac_customize_agent_comp_1_c ON cac_customize_agent_comp_cstm.id_c = aos_products_cac_customize_agent_comp_1_c.aos_produca2b8nt_comp_idb 
     LEFT OUTER JOIN preps_contracted_reps_wn_writing_number_1_c ON preps_contracted_reps_wn_writing_number_1_c.preps_contracted_reps_wn_writing_number_1wn_writing_number_idb = wn_writing_number.id 
     LEFT OUTER JOIN preps_contracted_reps ON preps_contracted_reps_wn_writing_number_1_c.preps_cont9effed_reps_ida = preps_contracted_reps.id 
     LEFT OUTER JOIN preps_contracted_reps_cstm ON preps_contracted_reps.id = preps_contracted_reps_cstm.id_c 
     LEFT OUTER JOIN email_addr_bean_rel ON email_addr_bean_rel.bean_id = preps_contracted_reps_cstm.id_c 
     LEFT OUTER JOIN email_addresses ON email_addr_bean_rel.email_address_id = email_addresses.id 
     LEFT OUTER JOIN wn_writing_number_cstm ON wn_writing_number_cstm.id_c = wn_writing_number.id 
     WHERE wn_writing_number_cstm.wn_writing_number_id_c IN (SELECT id_c FROM `temp` WHERE layer = lastLayer) AND wn_writing_number.deleted = '0' AND preps_contracted_reps.deleted = '0' AND wn_writing_number.deleted = '0' AND email_addr_bean_rel.deleted = '0' 
     GROUP BY wn_writing_number.`name`; 

     SET lastInsertCount := ROW_COUNT(); 

     INSERT INTO `pendingBusiness`(`layer`, `title_c`, `name`, `rep_first_name`, `rep_last_name`, `id_c`, `contact_status_reps_c`, `investor_first_name`, `investor_last_name`, `product_detail`, `paperwork_status_c`, `next_step`, `outstanding_requirements_c`, `funding_status_c`, `funding_next_step_c`, `fulfillment_status_c`, `fulfillment_next_step_c`, `amount`, `stage`, `date_entered`, `case_manager`, `lost_sale_date_c`, `compensation_run_c`, `product_id`, `rep_state`, `investor_state`) 
     SELECT lastLayer + 1, 
     wn_writing_number_cstm.title_c, 
     wn_writing_number.`name`, 
     preps_contracted_reps.first_name, 
     preps_contracted_reps.last_name, 
     wn_writing_number_cstm.id_c, 
     preps_contracted_reps_cstm.contact_status_reps_c, 
     contacts.first_name, 
     contacts.last_name, 
     aos_products.`name`, 
     opportunities_cstm.paperwork_status_c, 
     opportunities.next_step, 
     opportunities_cstm.outstanding_requirements_c, 
     opportunities_cstm.funding_status_c, 
     opportunities_cstm.funding_next_step_c, 
     opportunities_cstm.fulfillment_status_c, 
     opportunities_cstm.fulfillment_next_step_c, 
     opportunities.amount, 
     opportunities_cstm.stage_c, 
     opportunities.date_entered, 
     CONCAT(users.first_name, " ", users.last_name) AS case_manager, 
     opportunities_cstm.lost_sale_date_c, 
     opportunities_cstm.compensation_run_c, 
     aos_products.id, 
     preps_contracted_reps.primary_address_state, 
     opportunities_cstm.state_of_residence_c 
    FROM wn_writing_number 
     LEFT OUTER JOIN preps_contracted_reps_wn_writing_number_1_c ON preps_contracted_reps_wn_writing_number_1_c.preps_contracted_reps_wn_writing_number_1wn_writing_number_idb = wn_writing_number.id 
     LEFT OUTER JOIN preps_contracted_reps ON preps_contracted_reps_wn_writing_number_1_c.preps_cont9effed_reps_ida = preps_contracted_reps.id 
     LEFT OUTER JOIN preps_contracted_reps_cstm ON preps_contracted_reps.id = preps_contracted_reps_cstm.id_c 
     LEFT OUTER JOIN wn_writing_number_cstm ON wn_writing_number_cstm.id_c = wn_writing_number.id 
     LEFT OUTER JOIN opportunities_cstm ON opportunities_cstm.wn_writing_number_id_c = wn_writing_number.id 
     LEFT OUTER JOIN contacts ON opportunities_cstm.contact_id_c = contacts.id 
     LEFT OUTER JOIN opportunities ON opportunities_cstm.id_c = opportunities.id 
     LEFT OUTER JOIN aos_products ON opportunities_cstm.aos_products_id_c = aos_products.id 
     LEFT OUTER JOIN users ON opportunities_cstm.user_id_c = users.id 
     WHERE opportunities.deleted = '0' AND wn_writing_number_cstm.wn_writing_number_id_c IN (SELECT id_c FROM `temp` WHERE layer = lastLayer) AND opportunities.date_entered >= DATE_SUB(NOW(),INTERVAL 1.5 YEAR) 
     GROUP BY opportunities_cstm.id_c; 

     SET lastLayer := lastLayer + 1; 
    END WHILE LayerLoop; 


    SELECT `title_c`, `name`, `rep_first_name`, `rep_last_name`, `id_c`, `contact_status_reps_c`, `investor_first_name`, `investor_last_name`, `product_detail`, `paperwork_status_c`, `next_step`, `outstanding_requirements_c`, `funding_status_c`, `funding_next_step_c`, `fulfillment_status_c`, `fulfillment_next_step_c`, `amount`, `stage`, `date_entered`, `case_manager`, `lost_sale_date_c`, `compensation_run_c`, `product_id`, `rep_state`, `investor_state` 
    FROM `pendingBusiness` 
    ORDER BY rep_first_name ASC; 

    DROP TABLE IF EXISTS `pendingBusiness`; 
END 
+0

有没有原因为什么你只使用'''左外部连接'''?至少任何出现在where子句中的表都可以转换为'''INNER JOIN''s,这会给你一个提升。如果你明白连接语句正在做什么,我会鼓励你将所有的连接转换为内部连接。 – Anand

+0

[这里](http://i.imgur.com/KXdIwmw.png)是为pendingBusiness表完成的'JOIN'语句的图表。只是踢,我把它们全部转换成'INNER JOINS',但是,没有行被返回。我对差异的理解是模糊的。我只知道做一个'LEFT OUTER JOIN'往往会返回我需要的东西。 –

+0

如果你不明白连接是如何工作的,至少应该将where子句中的任何表转换为内连接。 – Anand

回答

0

FWIW,你的查询功能上等同于以下内容。但是,以下内容具有易于阅读的优点。也就是说,您的GROUP BY子句将返回(可能)不确定的结果,除了name之外的所有结果。

SELECT 0 
    , k.title_c 
    , a.name 
    , g.first_name 
    , g.last_name 
    , k.id_c 
    , h.contact_status_reps_c 
    , g.phone_mobile 
    , h.contract_type_c 
    , j.email_address 
    FROM wn_writing_number a 
    JOIN wn_writing_number_cac_customize_agent_comp_1_c b 
    ON b.wn_writing946b_number_ida = a.id 
    JOIN cac_customize_agent_comp c 
    ON c.id = b.wn_writing3148nt_comp_idb 
    LEFT 
    JOIN cac_customize_agent_comp_cstm d 
    ON d.id_c = c.id 
    LEFT 
    JOIN aos_products_cac_customize_agent_comp_1_c e 
    ON e.aos_produca2b8nt_comp_idb = d.id_c 
    LEFT 
    JOIN preps_contracted_reps_wn_writing_number_1_c f 
    ON f.preps_contracted_reps_wn_writing_number_1wn_writing_number_idb = a.id 
    JOIN preps_contracted_reps g 
    ON g.id = f.preps_cont9effed_reps_ida 
    LEFT 
    JOIN preps_contracted_reps_cstm h 
    ON h.id_c = g.id 
    JOIN email_addr_bean_rel i 
    ON i.bean_id = h.id_c 
    LEFT 
    JOIN email_addresses j 
    ON j.id = i.email_address_id 
    JOIN wn_writing_number_cstm k 
    ON k.id_c = a.id 
WHERE k.wn_writing_number_id_c = passId 
    AND a.deleted = 0 
    AND g.deleted = 0 
    AND i.deleted = 0 
GROUP 
    BY a.name;