Wordpress, WooCommerce - save product is very slow - wordpress

Some products are extremely slow to save (30 sec)
here is a screen shot from the profiler:
I turn on Slow Query log in mysql, and found this query:
SELECT COUNT( DISTINCT ID )
FROM wpmf_posts p
LEFT JOIN (
SELECT object_id
FROM wpmf_term_relationships
WHERE term_taxonomy_id
IN ( 7 )
) AS exclude_join ON exclude_join.object_id = p.ID
INNER JOIN (
SELECT object_id
FROM wpmf_term_relationships
INNER JOIN wpmf_term_taxonomy
USING ( term_taxonomy_id )
WHERE term_id
IN ( 4246, 4247, 4254, 4257, 4263, 4280, 4290, 4335, 4375, 4397, 4486, 5114 )
) AS include_join ON include_join.object_id = p.ID
WHERE 1 =1
AND p.post_status = 'publish'
AND p.post_type = 'product'
AND exclude_join.object_id IS NULL
LIMIT 0 , 30
which returns 4799, and takes 27 sec:
# Time: 190127 8:38:29
# User#Host: lfytcoil_uprdb[lfytcoil_uprdb] # localhost []
# Query_time: 27.287704 Lock_time: 0.000076 Rows_sent: 1 Rows_examined: 483196982
Any idea what is the purpose of this query?
This is wpmf_term_taxonomy with id
product_visibility
The count shows
31234
This is a WooCommerce site with 10717 products,
I suspect that there too many products for WooCommerce to handle.
NOTE: after running delete FROMwpmf_term_relationshipswhereterm_taxonomy_id= 7 which deleted 31234, the save take only 2 sec
My question:
Is WooCommerce not able to handle 10717 products?
Is there a way to somehow improve the save?
e.g. by disabling this query? or by caching the result? or improve the DB structure? or install some smart modules?
I notice the call to wp_update_term_count, it seems that if I disable this call, then the problem will be solved, what could be the side effects of this?

The solution is explain in this issue:
https://github.com/woocommerce/woocommerce/issues/14900
you should replace the file includes/wc-term-functions.php
with this:
https://raw.githubusercontent.com/woocommerce/woocommerce/ec489ce1a0c9030a73080ada28f25162f441dfdb/includes/wc-term-functions.php

NOTE: My previous answer is wrong
I found you can defer term count by adding
wp_defer_term_counting(true);
before the save operation (i.e. in the beginning of the script)
Than do
wp_defer_term_counting(false);
at the end of the script,
which also run the term count

Related

DELETE from same table used in the WHERE

I have the following query that is supposed to delete from a table with a circular FK requirement;
DELETE FROM question
WHERE defaultGotoQuestionId IN (
SELECT id from question WHERE facilityId IN (
SELECT id FROM facility WHERE customerId NOT IN (1,76)
)
);
But I get the following error;
Table is specified twice, both as a target for 'DELETE' and as a separate source for data
I understand the error message - that I can't DELETE from a TABLE that I am specifying in the WHERE - I just can't seem to work out how to solve it, for myself.
I saw a few examples of using a join - but perhaps I am having an off day - because I have been iterating through copy/paste examples - but still can't manage it.
It works as a SELECT : In that the result gives me the records I want to delete;
SELECT id FROM question
WHERE defaultGotoQuestionId IN (
SELECT id from question WHERE facilityId IN (
SELECT id FROM facility WHERE customerId NOT IN (1,76)
)
);
Thanks for any help!
What version of MariaDB are you using?
DELETE :: Same Source and Target Table
Until MariaDB 10.3.1, deleting from a table with the same source and target was not possible. From MariaDB 10.3.1, this is now possible.
See dbfiddle.
In older versions of MariaDB (or in MySQL, for example), one option you can use is:
DELETE
`question`
FROM
`question`
INNER JOIN (
SELECT
`id`
FROM
`question`
WHERE
`defaultGotoQuestionId` IN (
SELECT
`id`
FROM
`question`
WHERE
`facilityId` IN (
SELECT
`id`
FROM
`facility`
WHERE
`customerId` NOT IN (1, 5)
)
)
) `der` ON
`question`.`id` = `der`.`id`;
See dbfiddle.

How to use top 1 from subquery in MariaDB?

Let's say I want to get the list of tickets, and for each ticket I want to find out the date of the latest post. In SQL Server I can do it this way:
select
Tickets.*
(
select top 1 [Date]
from Posts
where TicketId = Tickets.Id
order by [Date] desc
) as LatestPostDate
from Tickets
I realized that we can't use top 1 in MariaDB. And as I searched, we should use limit 1. But this does not work:
select
Tickets.*
(
select `Date`
from Posts
where TicketId = Tickets.Id
order by `Date` desc
limit 1
) as LatestPostDate
from Tickets
You can use LIMIT in a sub-query. You are just missing a comma in your query:
select
Tickets.*, <-- missing comma
(
select `Date`
from Posts
where TicketId = Tickets.Id
order by `Date` desc
limit 1
) as LatestPostDate
from Tickets
In fact sub-queries should always have a LIMIT 1 clause to make sure you always get only one row back.

Import drupal database table data to wordpress database

i have my current working site on wordpress. i want to import data from database which had in another server working on drupal. How can i import all the data from table in drupal site to my current working website database in wordpress. Please help me with this
First Option : Steps and applicable queries to migrate your Drupal database to WordPress:
1. Make a backup of both your Drupal and WordPress databases.
2. Before converting Drupal to WordPress, make sure that in your original Drupal install the taxonomies are correctly labeled. Step 11 will further discuss fixing taxonomy.
3. Create a new WordPress installation in a different database
from your Drupal installation. Name the different databases
‘drupal’ and ‘wordpress’.
4. Clear out previous content from the WordPress database by
running this command in your database’s SQL queries tab in
phpmyadmin.
TRUNCATE TABLE wordpress.wp_comments;
TRUNCATE TABLE wordpress.wp_links;
TRUNCATE TABLE wordpress.wp_postmeta;
TRUNCATE TABLE wordpress.wp_posts;
TRUNCATE TABLE wordpress.wp_term_relationships;
TRUNCATE TABLE wordpress.wp_term_taxonomy;
TRUNCATE TABLE wordpress.wp_terms;
5. Apply this code to convert over multiple users.
DELETE FROM wordpress.wp_users WHERE ID > 1;
DELETE FROM wordpress.wp_usermeta WHERE user_id > 1;
6. To migrate over tags, use the following code...
(To ensure duplicate names don’t get lost, make sure that the
Drupal term_data table has been cleaned of all duplicate names.)
REPLACE INTO wordpress.wp_terms
(term_id, `name`, slug, term_group)
SELECT DISTINCT
d.tid,
d.name,
REPLACE(LOWER(d.name), ' ', '_'), 0
FROM drupal.term_data d
INNER JOIN drupal.term_hierarchy h
USING(tid)
WHERE (1
)
;
INSERT INTO wordpress.wp_term_taxonomy
(term_id, taxonomy, description, parent)
SELECT DISTINCT
d.tid `term_id`,
'post_tag' `taxonomy`,
d.description `description`,
h.parent `parent`
FROM drupal.term_data d
INNER JOIN drupal.term_hierarchy h
USING(tid)
INNER JOIN drupal.term_node n
USING(tid)
WHERE (1
)
;
7. To convert over posts, apply the following query:
INSERT INTO wordpress.wp_posts
(id, post_author, post_date, post_content, post_title,
post_excerpt, post_name, post_modified, post_type,
`post_status`)
SELECT DISTINCT
n.nid `id`,
n.uid `post_author`,
FROM_UNIXTIME(n.created) `post_date`,
r.body `post_content`,
n.title `post_title`,
r.teaser `post_excerpt`,
IF(SUBSTR(a.dst, 11, 1) = '/', SUBSTR(a.dst, 12),
a.dst) `post_name`,
FROM_UNIXTIME(n.changed) `post_modified`,
n.type `post_type`,
IF(n.status = 1, 'publish', 'private') `post_status` FROM
drupal.node n
INNER JOIN drupal.node_revisions r
USING(vid)
LEFT OUTER JOIN drupal.url_alias a
ON a.src = CONCAT('node/', n.nid)
# If applicable, add more Drupal content types below.
WHERE n.type IN ('post', 'page', 'blog')
;
*If your Drupal installation has multiple post types, be sure to
add the name of the post type into this line: WHERE n.type IN
(‘post’, ‘page’, ‘blog’). Failure to do so will result in not all posts
types being converted over.
8. To combine post types in WordPress, run this script:
UPDATE wordpress.wp_posts
SET post_type = 'post' WHERE
post_type IN ('blog') ;
9. To define the post/tag relationship, apply the following:
INSERT INTO wordpress.wp_term_relationships (object_
id, term_taxonomy_id)
SELECT DISTINCT nid, tid FROM drupal.term_node
;
# Update tag counts.
UPDATE wp_term_taxonomy tt
SET `count` = (
SELECT COUNT(tr.object_id)
FROM wp_term_relationships tr
WHERE tr.term_taxonomy_id = tt.term_taxonomy_id
)
;
10.Apply this query to migrate comments:
INSERT INTO wordpress.wp_comments
(comment_post_ID, comment_date, comment_content,
comment_parent, comment_author,
comment_author_email, comment_author_url, comment_
approved)
SELECT DISTINCT
nid, FROM_UNIXTIME(timestamp), comment, thread, name,
mail, homepage, ((status + 1) % 2)
FROM drupal.comments
;
# Update comments count on wp_posts table.
UPDATE wordpress.wp_posts
SET `comment_count` = (
SELECT COUNT(`comment_post_id`)
FROM wordpress.wp_comments
WHERE wordpress.wp_posts.`id` = wordpress.wp_
comments.`comment_post_id`
)
;
11.You do not have to do anything if you want to keep your
Drupal images and files in the same location, but if you are
FTP-ing your files to the uploads folder in your WordPress
wp-content folder, use the following code to fix the image
URLs.
UPDATE wordpress.wp_posts SET post_content =
REPLACE(post_content, ‚“/files/‘, ‚“/wp-content/
uploads/‘);
12.To fix taxonomy (assuming you’ve set it up correctly in your
original Drupal site), use the following code:
UPDATE IGNORE wordpress.wp_term_relationships,
wordpress.wp_term_taxonomy
SET wordpress.wp_term_relationships.term_taxonomy_id =
wordpress.wp_term_taxonomy.term_taxonomy_id
WHERE wordpress.wp_term_relationships.term_taxonomy_id
= wordpress.wp_term_taxonomy.term_id
;
13.To assign author roles for your users, here’s the code:
INSERT IGNORE INTO wordpress.wp_users
(ID, user_login, user_pass, user_nickname, user_email,
user_registered, user_activation_key, user_status,
display_name)
SELECT DISTINCT
u.uid, u.mail, NULL, u.name, u.mail,
FROM_UNIXTIME(created), ‚' ', 0, u.name
FROM drupal.users u
INNER JOIN drupal.users_roles r
USING (uid)
WHERE (1
# Uncomment and enter any email addresses you want to
exclude below.
# AND u.mail NOT IN (‚test#example.com‘)
)
;
14.Here’s the code you can use to set the author role’s permissions:
INSERT IGNORE INTO wordpress.wp_usermeta (user_id,
meta_key, meta_value)
SELECT DISTINCT
u.uid, 'wp_capabilities',
'a:1:{s:6:“author“;s:1:“1“;}'
FROM drupal.users u
INNER JOIN drupal.users_roles r
USING (uid)
WHERE (1
# Uncomment and enter any email addresses you want to
exclude below.
# AND u.mail NOT IN ('test#example.com')
)
;
INSERT IGNORE INTO wordpress.wp_usermeta (user_id,
meta_key, meta_value)
SELECT DISTINCT
u.uid, 'wp_user_level', '2'
FROM drupal.users u
INNER JOIN drupal.users_roles r
USING (uid)
WHERE (1
# Remove and enter any email addresses you want to
exclude below.
# AND u.mail NOT IN ('test#example.com')
)
;
You can remove the number sign before the line that has
the email address and put your own in so that your remain
the administrator.
15.Use this code to assign and give administrator status:
UPDATE wordpress.wp_usermeta
SET meta_value = 'a:1:{s:13:“administrator“;s:1:“1“;}‘
WHERE user_id IN (1) AND meta_key = 'wp_capabilities' ;
UPDATE wordpress.wp_usermeta
SET meta_value = '10'
WHERE user_id IN (1) AND meta_key = 'wp_user_level'
;
16.This code will help assign authors to the posts they wrote:
UPDATE wordpress.wp_posts
SET post_author = NULL
WHERE post_author NOT IN (SELECT DISTINCT ID FROM
wordpress.wp_users)
;
17. You can then feed the following code for the editor to help
clean it up so that your posts don’t look bizarre after the
conversion.
UPDATE wordpress.wp_posts
SET post_name =
REVERSE(SUBSTRING(REVERSE(post_
name),1,LOCATE('/',REVERSE(post_name))-1)) ;
That’s the basics of migrating your Drupal site to WordPress.
Second Option : Using with Plugin To Migrate you Drupal Database to Wordpress
In this section, we’ll be using the FG Drupal to WordPress plugin to carry out our migration. This tool is remarkably simple to use, and we’ll cover how to use it in this piece. However, if you do happen to run into any errors, the plugin’s documentation should see you through.
It’s worth noting this plugin also comes in a premium version, but the free option is more than enough to carry out a regular migration. However, if you’re looking to move multiple authors, your comments, users, and even custom post types, the premium version might be worth considering.
Step #1: Install and activate the FG Drupal to WordPress plugin
Step #2: Find out your Drupal database parameters
Step #3: Import your Drupal content into WordPress
Get more details, you can follow the link - How to migrate Drupal to WordPress (in 3 steps)

Where-Condition as IN(Subquery) with Doctrine2 in Symfony2.3.1 doesnt work

---- Done with Symfony2.3.1 and Doctrine2 ----
Sorry, i hope i was not too stupid to find a suitable solution for my problem. I try to build a Query for hours.
SELECT * FROM product
WHERE product_id in
(
SELECT product_id from (
SELECT count(*) as result_amount, product_id FROM product_x_attribut
JOIN productattribut on productattribut_id = productattribut.id
WHERE (
productkey = "price" and
stringType = "premium"
) or (
productkey = "size" and
stringType = "S"
)
GROUP BY product_id
HAVING result_amount = 2
) as temp
)
GROUP BY product_id
ORDER BY p0_.name ASC
This is the SQL which works fine in phpmyAdmin.
This can be seen like
Select * from abc where abc.x in ( Select * from ( select * from ) as abcd )
So there is one core query, i call it subSubQuery, the second query around the core will be called subQuery and the outer Query is just the outer Query, no a Subquery.
I could build the subSubQuery with Doctrine2.
But i cannot built the subQuery like this
Select product_id from ( $subSubQuery->getQuery()->getDQL() )
I want to do the subQuery like this
$subQuery = $repositoryProduct->createQueryBuilder('product');
$subQuery->add('select', 'product_id');
$subQuery->add('from',$subSubQuery->getDQL() );
// However to set an alias is a miracle for me, this didnt work off course
$subQuery->add('as','tmp' );
This is the subQuery.
I also cannot build the outer Query
Select * from abc where abc.x in ( $subQuery->getQuery()->getDQL() )
I want to do this like this
$query->where(
$query->expr()->in('product.id', $subQuery->getDQL() )
);
But i try to build this with Doctrine2 like this:
I am so down, i tried ->getSQL(), ->getDQL(), i tried as much as i was able to detect as a suitable tiny step to a solution for this problem and i has tried as much keyword in google as my finger were able to write... I hope someone could help me to find a solution...
Thanks a lot to each helpful advise.
I know that statements like this work:
$qbGames->andWhere($qbGames->expr()->in('game.id',$qbGameId->getDQL()));
Your question is kind of hard to follow. Consider using pastebin to show all your mappings as they currently exist. And then maybe presenting a simplieid query?
My $qbGameId query was built with:
$qbGameId = $em->createQueryBuilder();
$qbGameId->addSelect('distinct gameGameId.id');
$qbGameId->from('ZaysoCoreBundle:Event','gameGameId');
// Assorted joins and where conditions

wordpress generating slow mysql queries - is it index problem?

I've got very slow Mysql queries coming up from my wordpress site. It's making everything slow and I think this is eating up CPU usage. I've pasted the Explain results for the two most frequently problematic queries below. This is a typical result - although very occasionally teh queries do seem to be performed at a more normal speed.
I have the usual wordpress indexes on the database tables. You will see that one of the queries is generated from wordpress core code, and not from anything specific - like the theme - for my site.
I have a vague feeling that the database is not always using the indexes/is not using them properly...
Is this right? Does anyone know how to fix it? Or is it a different problem entirely?
Many thanks in advance for any help anyone can offer - it is hugely appreciated
Query: [wp-blog-header.php(14): wp()]
SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 6
id
select_type
table
type
possible_keys
key
key_len
ref
rows
Extra
1
SIMPLE
wp_posts
ref
type_status_date
type_status_date
63
const
427
Using where; Using filesort
Query time: 34.2829 (ms)
9) Query: [wp-content/themes/LMHR/index.php(40): query_posts()]
SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.ID NOT IN ( SELECT tr.object_id FROM wp_term_relationships AS tr INNER JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy = 'category' AND tt.term_id IN ('217', '218', '223', '224') ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 0, 6
id
select_type
table
type
possible_keys
key
key_len
ref
rows
Extra
1
PRIMARY
wp_posts
ref
type_status_date
type_status_date
63
const
427
Using where; Using filesort
2
DEPENDENT SUBQUERY
tr
ref
PRIMARY,term_taxonomy_id
PRIMARY
8
func
1
Using index
2
DEPENDENT SUBQUERY
tt
eq_ref
PRIMARY,term_id_taxonomy,taxonomy
PRIMARY
8
antin1_lovemusic2010.tr.term_taxonomy_id
1
Using where
Query time: 70.3900 (ms)
Check this http://core.trac.wordpress.org/ticket/10964
The problem is SQL_CALC_NUM_ROWS, WordPress set this param automatically when you execute get_posts query, this make a slow query.
You can try wp-cache plugin.
Also you can read this article it explains that SQL_CALC_FOUND_ROWS not the best solution at queries.

Resources