0

Je tente d'optimiser cette procédure stockée. Actuellement, cette itération, lorsqu'elle est effectuée du haut de la chaîne, peut prendre de 2,4 à 2,7 secondes. J'adorerais descendre à moins de 1 seconde si possible.Amélioration des performances de cette procédure stockée dans MySQL

J'ai fait des recherches sur ce que je peux faire pour optimiser cela et la plupart des conseils de MySQL ne fonctionnent pas. Vous ne pouvez pas LOCK tables ou utiliser les instructions LOAD DATA à l'intérieur des procédures stockées. Lors de l'exécution des tests, il semble que les instructions INSERT INTO SELECT prennent le plus de temps dans cette requête.

Lorsque j'ai couru un appel, j'ai obtenu 2,6 secondes avec environ 13 INSERT INTO déclarations tirant. Au moins 3 ont pris 0,43-0,45 secondes à compléter. Toutes les autres déclarations ont pris très peu de temps à compléter.

Voici mes paramètres actuels dans mon fichier '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 

Voici ma procédure stockée:

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

Y at-il une raison pour laquelle vous utilisez uniquement '' 'LEFT OUTER JOIN'''s? Au moins n'importe quelle table apparaissant dans la clause where peut être convertie en '' INNER JOIN''' et cela devrait vous donner un coup de pouce. Si vous comprenez ce que font les instructions de jointure, je vous encourage à convertir toutes les jointures en jointures internes. – Anand

+0

[ici] (http://i.imgur.com/KXdIwmw.png) est un diagramme de l'instruction 'JOIN' effectuée pour la table pendingBusiness. Juste pour les coups de pied, je les ai tous convertis en «JEUX INTERIEURS», cependant, aucune ligne n'a été retournée. Ma compréhension de la différence est floue. Je sais juste que faire un "OUFT OUTER JOIN" renvoie souvent ce dont j'ai besoin. –

+0

Si vous ne comprenez pas le fonctionnement des jointures, essayez au moins de convertir toute table dans where en jointures internes. – Anand

Répondre

0

FWIW, votre requête est fonctionnellement identique à ce qui suit. Cependant, ce qui suit a l'avantage d'être plus facile à lire. Cela dit, votre clause GROUP BY renvoie des résultats (potentiellement) indéterminés pour tous sauf 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;