提高MySQL中存储过程的性能

时间:2017-06-06 20:19:51

标签: mysql loops stored-procedures database-performance insert-into

我正在尝试优化此存储过程。目前,这个迭代从链的最顶端完成,可能需要大约2.4-2.7秒。如果可能的话,我希望将其降至1秒以下。

我已经研究过我可以做些什么来优化这一点,并且MySQL的大部分提示都不起作用。您不能LOCK表或使用存储过程内的LOAD DATA语句。运行测试时,似乎INSERT INTO SELECT语句占用此查询的时间最多。

当我运行一个CALL时,我得到2.6秒,大约有13 INSERT INTO个语句被解雇。至少3个完成了0.43-0.45秒。所有其他陈述只花了很少时间才完成。

以下是我在my.cnf' 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

1 个答案:

答案 0 :(得分: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;