MySql Query Hangs when using LIKE statement

2019-09-15 00:25发布

问题:

I am trying to set up alerts within Wordpress so that users can create alerts so that they will be notified when a new post (property) that is created matches their set criteria (alerts). My plan was to do this using two post types one for properties and one for the alerts. Then when a property post is saved it will perform the following example query:

SELECT 
    post_author
    FROM 
        wp_posts
    INNER JOIN wp_postmeta m1
        ON wp_posts.ID = m1.post_id
        AND m1.meta_key = 'a_property_type'
        AND m1.meta_value = 'flat'
    INNER JOIN wp_postmeta m2
        on wp_posts.ID = m2.post_id
        AND m2.meta_key = 'a_bedrooms_min' 
        AND m2.meta_value <= '2'
    INNER JOIN wp_postmeta m3
        on wp_posts.ID = m3.post_id
        AND m3.meta_key = 'a_bedrooms_max' 
        AND m3.meta_value >= '2'
    INNER JOIN wp_postmeta m4
        on wp_posts.ID = m4.post_id
        AND m4.meta_key = 'a_bathrooms_min' 
        AND m4.meta_value <= '2'
    INNER JOIN wp_postmeta m5
        on wp_posts.ID = m5.post_id
        AND m5.meta_key = 'a_bathrooms_max' 
        AND m5.meta_value >= '2'      
    INNER JOIN wp_postmeta m6
        on wp_posts.ID = m6.post_id
        AND m6.meta_key = 'a_garden' 
        AND m6.meta_value >= '1'        
    INNER JOIN wp_postmeta m7
        on wp_posts.ID = m7.post_id
        AND m7.meta_key = 'a_garage' 
        AND m7.meta_value >= '1'    
    INNER JOIN wp_postmeta m8
        on wp_posts.ID = m8.post_id
        AND m8.meta_key = 'a_parking' 
        AND m8.meta_value >= '1'        
    INNER JOIN wp_postmeta m9
        on wp_posts.ID = m9.post_id
        AND m9.meta_key = 'a_double_glazing' 
        AND m9.meta_value >= '1'    
    INNER JOIN wp_postmeta m10
        on wp_posts.ID = m10.post_id
        AND m10.meta_key = 'a_country' 
        AND m10.meta_value LIKE 'Scotland'        
    WHERE
        wp_posts.post_type = 'alerts'
        AND wp_posts.post_status = 'publish'
    GROUP BY 
       wp_posts.ID
    ORDER BY 
        wp_posts.post_date DESC

This works and does return the properties matching the criteria set however when I introduce a LIKE it really makes the query hang. I am working with the default Wordpress tables 'wp_posts' and 'wp_postmeta'. I have tried setting an index on the column 'meta_value' but because its a 'longtext' field it wont allow me to.

Is there a better solution to do this or can my Query be written more efficiently?

Thanks

回答1:

Aside from what eggyal offered, I too would add an index on (post_id, meta_key, meta_value). If that does not help your query, I would TRY one other thing. Pre-wrap all elements EXCEPT the LIKE into a prequery such that the inner query gets processed first and returns a very small set of IDs, THEN join to the LIKE condition.

Lets say you have 1000 properties, but only 35 qualify with all your other criteria and is resolved in sub-second time. Now you have only 35 records that will be ATTEMPTED to your additional LIKE condition. Something like

select
      wp.Post_Author
   from
      ( SELECT 
              post_id,
              post_author
           FROM 
              wp_posts
                 INNER JOIN wp_postmeta m1
                    ON wp_posts.ID = m1.post_id
                   AND m1.meta_key = 'a_property_type'
                 INNER JOIN the m2 through m9 
           WHERE
               type and status criteria ) as PreQuery
      INNER JOIN your m10 version
         on  PreQuery.Post_ID = m10.post_id
        AND ... rest of join condition