MySQL query optimization in Wordpress - mysql

Can any one re-write this SQL query to perform better?
At present this query takes about 29 seconds to execute in BlueHost server while it takes 6 seconds in HostGator.com server.
My intention is to delete all records exists in wp_postmeta table of post type='attachment' and with meta_key='_mycbgenie_managed_by'
DELETE FROM wp_postmeta
WHERE post_id IN
( SELECT ID FROM wp_posts
WHERE post_type = 'attachment'
AND post_parent IN
( SELECT ID FROM
( SELECT ID FROM wp_posts a
LEFT JOIN wp_postmeta b ON (a.ID = b.post_id)
LEFT JOIN wp_postmeta AS mt1 ON (a.ID = mt1.post_id)
WHERE post_type = 'product' AND mt1.meta_key = '_mycbgenie_managed_by'
) AS taskstodelete
)
)

DELETE PM FROM wp_postmeta as PM
INNER JOIN
wp_posts as P
ON PM.post_id=P.ID AND P.post_type='attachment'
INNER JOIN wp_posts as P2
ON P.post_parent=P2.ID
INNER JOIN wp_postmeta AS PM2
ON P2.ID = PM2.post_id
WHERE P2.post_type = 'product' AND PM2.meta_key = '_mycbgenie_managed_by'

Related

Get list of products that don't have a specific taxonomy in WooCommerce

I've hit an issue trying to find out what products are missing suppliers on a website with tens of thousands of products.
I need an MySQL query to determine which products are missing the taxonomy "suppliers" through phpmyadmin.
So far I've pieced this together from various answers:
SELECT *
FROM wp_posts wp
INNER JOIN wp_postmeta wm ON (wm.`post_id` = wp.`ID`)
INNER JOIN wp_term_relationships wtr ON (wp.`ID` = wtr.`object_id`)
INNER JOIN wp_term_taxonomy wtt ON (wtr.`term_taxonomy_id` = wtt.`term_taxonomy_id`)
INNER JOIN wp_terms wt ON (wt.`term_id` = wtt.`term_id`)
AND wtt.`taxonomy` = 'suppliers'
WHERE post_type = 'product'
GROUP BY wp.ID
I've tried numerous things and cannot get it to work.
The problem is with you query is that you are not excluding product that has suppliers that that product has some other attributes, so you can use NOT EXIST or NOT IN, I have written the query using NOT EXIST.
SELECT *
FROM wp_posts wp
INNER JOIN wp_postmeta wm ON wm.`post_id` = wp.`ID`
INNER JOIN wp_term_relationships wtr ON (wp.`ID` = wtr.`object_id`)
INNER JOIN wp_term_taxonomy wtt ON wtr.`term_taxonomy_id` = wtt.`term_taxonomy_id`
INNER JOIN wp_terms wt ON wt.`term_id` = wtt.`term_id`
WHERE post_type = 'product'
AND NOT EXISTS
(SELECT `object_id`
FROM `wp_term_relationships` AS wtr_inner
WHERE `term_taxonomy_id` IN
(SELECT term_taxonomy_id
FROM `wp_term_taxonomy`
WHERE `taxonomy` = 'suppliers')
AND wtr.object_id = wtr_inner.object_id )
GROUP BY wp.ID
Another version which will be a bit faster if you know all the suppliers term_taxonomy_id So you can modify the above query as
SELECT *
FROM wp_posts wp
INNER JOIN wp_postmeta wm ON wm.`post_id` = wp.`ID`
INNER JOIN wp_term_relationships wtr ON (wp.`ID` = wtr.`object_id`)
INNER JOIN wp_term_taxonomy wtt ON wtr.`term_taxonomy_id` = wtt.`term_taxonomy_id`
INNER JOIN wp_terms wt ON wt.`term_id` = wtt.`term_id`
WHERE post_type = 'product'
AND NOT EXISTS
(SELECT `object_id`
FROM `wp_term_relationships` AS wtr_inner
WHERE `term_taxonomy_id` IN (27,28,29) -- replace it will all suppliers term_taxonomy_id
AND wtr.object_id = wtr_inner.object_id )
GROUP BY wp.ID
Hope this helps!

delete with 2 join get error - mysql

I'm trying to run this delete query in MYSQL (via phpMyAdmin) ANd I keep getting this error :
DELETE
p,pm
from wp_posts p
inner join wp_postmeta pm on pm.post_id = p.id
where p.id in (SELECT MIN( id ) AS min_id
FROM wp_posts inner join wp_postmeta on (wp_posts.ID=wp_postmeta.post_id and meta_key = 'old_id')
WHERE post_type = 'post'
GROUP BY meta_value
HAVING COUNT( * ) > 1)
any idea why ?
Looking to your code
You don't should use as in subselect for IN clause
DELETE p, pm
from wp_posts as p
inner join wp_postmeta as pm on pm.post_id = p.id
where p.id in (SELECT MIN( id )
FROM wp_posts
inner join wp_postmeta on (wp_posts.ID=wp_postmeta.post_id
and meta_key = 'old_id')
WHERE post_type = 'post'
GROUP BY meta_value
HAVING COUNT( * ) > 1)

Show the values in one row with same id in sql

I have Three tables and I join the table and retrieve all the values in this query
sql query:
SELECT wp_term_relationships.object_id, wp_posts.post_title,
wp_postmeta.meta_key, wp_postmeta.meta_value
FROM `wp_posts` , wp_postmeta, wp_term_relationships
WHERE (wp_posts.ID = wp_postmeta.post_id)
AND (wp_postmeta.post_id = wp_term_relationships.object_id)
AND wp_term_relationships.term_taxonomy_id =33
Its Show Table structure is this
object_id post_title meta_key meta_value
302 CHICKEN CHOW MEIN post_image url1
302 CHICKEN CHOW MEIN price 6.95
I want Show the OBject Id in one and merge the two rows in one column i want like this
object_id post_title meta_value(price) meta_value(post_image)
302 CHICKEN CHOW MEIN 6.95 url1
You could join to wp_postmeta twice, using more usual join syntax
SELECT rel.object_id, p.post_title,
meta_price.meta_key, meta_price.meta_value,
meta_image.meta_key, meta_image.meta_value
FROM `wp_posts` p
inner join wp_postmeta meta_price on meta_price.post_id = p.ID
inner join wp_postmeta meta_image on meta_image.post_id = p.ID
inner join wp_term_relationships rel on rel.objet_id = p.ID
WHERE rel.term_taxonomy_id = 33
and meta_price.meta_key = 'price'
and meta_image.meta_key = 'post_image'
(Syntax not checked – no access to a WordPress db here – and you'll need to change the selected columns slightly.)
If it was me, I'd simply stick with your existing query, and handle the pivot in the application code, so.
*PHP goes here*
$query = "
SELECT r.object_id
, p.post_title
, m.meta_key
, m.meta_value
FROM wp_posts p
JOIN wp_postmeta m
ON m.post_id = p.ID
JOIN wp_term_relationships r
ON r.object_id = m.post_id
WHERE r.term_taxonomy_id = 33
ORDER
BY post_title
, meta_key;
";
*More PHP goes here*
Syntax not checked, but something like this?
SELECT object_id, post_title, max(meta_key_price) as key_price, max(meta_key_image) as key_image FROM
(
SELECT
wp_term_relationships.object_id,
wp_posts.post_title,
case meta_key when 'price' then meta_value else null end as meta_key_price,
case meta_key when 'post_image' then meta_value else null end as meta_key_image
FROM `wp_posts` , wp_postmeta, wp_term_relationships
WHERE (wp_posts.ID = wp_postmeta.post_id)
AND (wp_postmeta.post_id = wp_term_relationships.object_id)
AND wp_term_relationships.term_taxonomy_id =33
) as t group by object_id

Mysql delete similar post : can't specify target table 'wp_posts' for update in FROM clause

After an importing error, there is many duplicate content from my posts.
Then, I try to delete this posts with that query :
DELETE
FROM wp_posts USING wp_posts
LEFT JOIN wp_postmeta pm ON wp_posts.ID = pm.post_id
AND pm.meta_key="_wpbdp[fields][6]"
LEFT JOIN wp_wpbdp_listing_fees wlf ON wp_posts.ID = wlf.listing_id
WHERE wp_posts.post_type="wpbdp_listing"
AND wp_posts.post_status="publish"
AND EXISTS (
SELECT NULL
FROM wp_posts p2
LEFT JOIN wp_postmeta pm2 ON p2.ID = pm2.post_id
AND pm2.meta_key="_wpbdp[fields][6]"
LEFT JOIN wp_wpbdp_listing_fees wlf2 ON p2.ID = wlf2.listing_id
WHERE p2.post_type="wpbdp_listing"
AND pm2.meta_value=pm.meta_value
AND p2.post_status="publish"
AND wlf2.category_id=wlf.category_id
)
Unfortunately, I can't do a SELECT statement who calls the same table that I want to delete.
Is there another solution ?
I tried something new, and it passed.
Following the #Nick's idea, I did that query :
DELETE p
FROM wp_posts p, wp_posts p2
WHERE p.post_title = p2.post_title
AND p.post_type="wpbdp_listing"
AND p2.post_type="wpbdp_listing"
AND p2.post_status="publish"
AND p.post_status="publish"
AND EXISTS(
SELECT NULL
FROM wp_wpbdp_listing_fees wlf
WHERE p.ID = wlf.listing_id
AND EXISTS (
SELECT NULL
FROM wp_wpbdp_listing_fees wlf2
WHERE wlf2.category_id = wlf.category_id
AND p.ID = wlf2.listing_id
)
)
AND EXISTS(
SELECT NULL
FROM wp_postmeta pm
WHERE p.ID = pm.post_id
AND pm.meta_key="_wpbdp[fields][6]"
AND EXISTS (
SELECT NULL
FROM wp_postmeta pm2
WHERE pm2.meta_key="_wpbdp[fields][6]"
AND p.ID = pm2.post_id
AND pm2.meta_value=pm.meta_value
)
)
AND p.ID < p2.ID
It's very ugly and not optimised, but it works !
By the way, thanks for your answers !

How to merge two SQL queries to get latest Wordpress Post and Featured Image

I'm trying to show latest Post Excerpt, Post Title and Featured Image on an ASP page. To simplify the query I add the Permalink as a custom field for each Post. I have a query that gets all except Featured Image and I have another query that gets Featured image but I can't work out how to merge them into one query.
// Gets Post Excerpt and Post Title
SELECT
wp_posts.id,
wp_posts.post_title,
wp_postmeta.meta_value,
wp_postmeta.meta_key,
wp_posts.post_excerpt
FROM
wp_postmeta
INNER JOIN wp_posts p ON (wp_postmeta.post_id = wp_posts.ID)
WHERE post_id IN (
SELECT wp_posts.id
FROM wp_posts
WHERE post_type = 'post'
AND post_status = 'publish'
AND meta_key = 'my_permalink'
ORDER BY post_date, wp_posts.id
)
ORDER BY wp_posts.post_date DESC, wp_postmeta.post_id
LIMIT 2
// Gets Featured Images for a Post
SELECT p.*
FROM wp_postmeta AS pm
INNER JOIN wp_posts AS p ON pm.meta_value=p.ID
WHERE pm.post_id = $ID
AND pm.meta_key = '_thumbnail_id'
ORDER BY p.post_date DESC
Can anyone help me merge these queries? Thanks.
Sample data to be returned:
ID | post_title | post_excerpt | meta_value_my_permalink | featured_image_guid
** UPDATE *
I've managed to get the following which works fine except I can't get more that one row as I get an error when I try and use 'IN' in a subquery
e.g. pm2.post_id IN (SELECT wp_posts.id FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 2)
SELECT
p.post_title,
p.post_excerpt,
pm.meta_value AS permalink,
p2.guid as thumbnail,
p2.post_title as image_alt
FROM
wp_postmeta pm
INNER JOIN wp_posts p ON (pm.post_id = p.ID),
wp_postmeta pm2
INNER JOIN wp_posts p2 ON (pm2.meta_value = p2.ID)
WHERE
pm.post_id = (SELECT wp_posts.id FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 1) AND
pm.meta_key = 'my_permalink' AND
pm2.post_id = (SELECT wp_posts.id FROM wp_posts WHERE post_type = 'post' AND post_status = 'publish' ORDER BY post_date DESC LIMIT 1) AND
pm2.meta_key = '_thumbnail_id'
It is difficult to see what you are trying to get without some sample data but I think that you know the post ID and need the info from both the my_permakink and _thumbnail_id keys?
Since I'm on a tablet I will give you the bare bones only and let you limit the result set and filter it.
Select *
From wp_posts p
Inner join
Wp_postmeta pm1 on p.id = pm1.post_id and metakey = 'my_permalink'
Inner join
Wp_postmeta pm2 on p.id = pm1.post_id and metakey = '_thumbnail_id'
This will give you every post that has an image with the info for both metakeys. If you want the info for posts without an image change the second inner join to a left join.
A bunch of joins and a view as the subquery has given me what I need.
SELECT
p.post_title,
p.post_excerpt,
pm.meta_value AS permalink,
p2.guid AS thumbnail,
p2.post_title AS thumbnail_alt
FROM
wp_postmeta pm
INNER JOIN wp_posts p ON (pm.post_id = p.ID)
INNER JOIN wp_postmeta pm2 ON (pm2.post_id = p.ID)
INNER JOIN wp_posts p2 ON (pm2.meta_value = p2.ID)
WHERE
pm.meta_key = 'my_permalink' AND
pm2.meta_key = '_thumbnail_id' AND
p.ID IN (SELECT * FROM vwLatestPostIds)
Use this to retrieve the post title, post id, post featured thumbnail url, post category etc -
"SELECT a.ID id, a.post_title title, a.post_content content,taxonomy, name, a.post_date_gmt postdate,max(c.guid) img_url
FROM kb_posts a
JOIN kb_term_relationships tr
ON (a.id = tr.object_id)
JOIN kb_term_taxonomy tt
ON (tr.term_taxonomy_id = tt.term_taxonomy_id AND tt.taxonomy='category')
JOIN kb_terms t
ON (t.term_id = tt.term_id AND t.term_id = $user_id)
LEFT JOIN
(select post_parent, max(post_date_gmt) as latest_image_date from kb_posts
where post_type='attachment' GROUP BY post_parent) b
on a.id=b.post_parent
LEFT JOIN kb_posts c
on c.post_parent=a.id
and c.post_type='attachment'
and b.latest_image_date = c.post_date_gmt where c.guid IS NOT NULL
GROUP BY a.ID ORDER BY a.ID DESC LIMIT 5"