简体   繁体   中英

Writing Mysql Query more efficient

How can I make this below Mysql query more efficient ?

SELECT
   DISTINCT crm_task_id,
   table_header_id  
FROM
   table_details  
WHERE
   table_header_id  IN (
      SELECT
         table_header_id  
      FROM
         table_header  
      WHERE
         crm_campaign_id =196  
         AND crm_campaign_post_code_id  IN (
            SELECT
               crm_campaign_post_code_id  
            FROM
               crm_campaign_post_code  
            WHERE
               is_display_operator  IN (
                  1, 0 
               )  
         )  
         AND g_user_id  IN (
            SELECT
               g_user_id  
            FROM
               crm_user  
            WHERE
               is_active =1  
         )  
         AND DATE_FORMAT( created,  '%Y-%m-%d' )   BETWEEN  '2015-12-01'  AND  '2016-01-04'  
      )  
      AND crm_task_id NOT   IN (
         SELECT
            crm_task_id  
         FROM
            table_details  
         WHERE
            table_header_id  IN (
               SELECT
                  table_header_id  
               FROM
                  table_header  
               WHERE
                  crm_campaign_id =196  
                  AND crm_post_code_categ_id !=1000  
            )  
         )

table_header columns :

| table_header_id           | bigint(20)  
| created                   | datetime     
| updated                   | datetime    
| createdby                 | bigint(20)   
| updatedby                 | bigint(20)   
| is_active                 | char(1)     
| crm_user_session_id       | bigint(20)   
| crm_campaign_id           | bigint(20)   
| crm_post_code_categ_id    | bigint(20)  
| value                     | varchar(128) 
| crm_campaign_post_code_id | bigint(20)   
| crm_filter_id             | bigint(20)  
| g_user_id                 | bigint(20)  
| session_time              | int(100) 

table_details Columns:

| table_details_id | bigint(11)  
| table_header_id         | bigint(11) 
| created                   | datetime    
| updated                   | datetime  
| createdby                 | bigint(11)
| updatedby                 | bigint(11) 
| is_active                 | smallint(5)
| crm_contact_id            | varchar(60)
| crm_task_id               | bigint(11)

the above query takes more than 2 seconds to return result, Please can anyone rewrite this query to return result faster !!!

Try this one.

SELECT
   DISTINCT td.crm_task_id,
   td.table_header_id      
FROM
   table_details td      
join
   table_header th 
      on th.table_header_id = td.table_header_id 
      and th.crm_campaign_id =196 
      and th.crm_post_code_categ_id !=1000      
join
   crm_campaign_post_code ccpc 
      on ccpc.crm_compaign_post_code_id =  th.crm_campaign_post_code_id 
      and ccpc.is_display_operator IN (
         1,
      0 ) 
      and DATE_FORMAT( created,
      '%Y-%m-%d' ) BETWEEN  '2015-12-01' AND  '2016-01-04'      
   join
      crm_user cr 
         on cr.g_user_id = ccpc.g_user_id 
         and cr.is_active = 1

try this

 SELECT DISTINCT crm_task_id, td.table_header_id
    FROM table_details td
    WHERE table_header_id 
    JOIN table_header th
    ON td.table_header_id = th.table_header_id
    AND th.crm_campaign_id =196
    JOIN crm_campaign_post_code c
    ON c.crm_campaign_post_code_id = th.crm_campaign_post_code_id
    AND is_display_operator IN ( 1, 0 ) 
    JOIN crm_user u
    ON u.g_user_id = c.g_user_id
    AND is_active =1
    AND DATE_FORMAT( created,  '%Y-%m-%d' ) 
    BETWEEN  '2015-12-01'
    AND  '2016-01-04'
    WHERE u.crm_task_id  NOT 
    IN (
    SELECT IFNULL(crm_task_id,0)
    FROM table_details
    WHERE table_header_id
    IN (
    SELECT table_header_id
    FROM table_header
    WHERE crm_campaign_id =196
    AND crm_post_code_categ_id !=1000
   ))

Try this one :

    SELECT DISTINCT crm_task_id, table_header_id
FROM table_details
WHERE table_header_id
IN (
    select table_header_id From 
    (
    SELECT table_header_id
    FROM table_header
    WHERE crm_campaign_id =196
    AND crm_campaign_post_code_id
    IN (

        select crm_campaign_post_code_id from (
        SELECT crm_campaign_post_code_id
        FROM crm_campaign_post_code
        WHERE is_display_operator
        IN ( 1, 0 )
        ) temp2
    )
    AND g_user_id
    IN (
        select g_user_id from (
        SELECT g_user_id
        FROM crm_user
        WHERE is_active =1
        ) temp3
    )
    AND DATE_FORMAT( created,  '%Y-%m-%d' ) BETWEEN  '2015-12-01' AND  '2016-01-04'
    ) as temp_1
)
AND crm_task_id NOT IN (
    SELECT crm_task_id FROM table_details WHERE table_header_id
    IN (
        select table_header_id From (
        SELECT table_header_id
        FROM table_header
        WHERE crm_campaign_id =196
        AND crm_post_code_categ_id !=1000
        ) temp4
    )
)

Avoid IN ( SELECT ... ) ; it does not optimize well. Instead turn it into a JOIN . For example:

SELECT  crm_task_id
    FROM  table_details
    WHERE  table_header_id IN (
        SELECT  table_header_id
            From  
              ( SELECT  table_header_id
                    FROM  table_header
                    WHERE  crm_campaign_id =196
                      AND  crm_post_code_categ_id !=1000 ) temp4 )

-->

SELECT  crm_task_id
    FROM  table_details AS d
    JOIN  table_header AS h ON d.table_header_id = h.table_header_id
    WHERE  h.crm_campaign_id =196
      AND  h.crm_post_code_categ_id !=1000 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM