I'm hoping somebody can help me, I've got a woocommerce install that 504 errors when adding a product with six attributes to the cart. There is one 'catchall' variation set up for the product. I have disabled all plugins and reverted to the storefront theme and still experience the same issue, it appears to be directly related to a very slow SQL query that is being run.
The query appears to be selecting the post ID where the meta values for the attribute match the selected attributes which in this case is suboptimal as there are 70k entries in the post_meta table and hundreds in the post table. This query does not complete in a reasonable timeframe and is called more than once so kills off the SQL server. Personally I was able to rewrite the query to be much faster in mysql workbench but I can't figure out where it's being generated. The query is as follows:
SELECT wp_posts.ID FROM wp_posts LEFT JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) LEFT JOIN wp_postmeta AS mt1 ON (wp_posts.ID = mt1.post_id AND mt1.meta_key = 'attribute_pa_workbee-size-drive' ) LEFT JOIN wp_postmeta AS mt2 ON ( wp_posts.ID = mt2.post_id ) LEFT JOIN wp_postmeta AS mt3 ON (wp_posts.ID = mt3.post_id AND mt3.meta_key = 'attribute_pa_extrusion-colour' ) LEFT JOIN wp_postmeta AS mt4 ON ( wp_posts.ID = mt4.post_id ) LEFT JOIN wp_postmeta AS mt5 ON (wp_posts.ID = mt5.post_id AND mt5.meta_key = 'attribute_pa_router' ) LEFT JOIN wp_postmeta AS mt6 ON ( wp_posts.ID = mt6.post_id ) LEFT JOIN wp_postmeta AS mt7 ON (wp_posts.ID = mt7.post_id AND mt7.meta_key = 'attribute_pa_dust-shoe' ) LEFT JOIN wp_postmeta AS mt8 ON ( wp_posts.ID = mt8.post_id ) LEFT JOIN wp_postmeta AS mt9 ON (wp_posts.ID = mt9.post_id AND mt9.meta_key = 'attribute_pa_cam-software' ) LEFT JOIN wp_postmeta AS mt10 ON ( wp_posts.ID = mt10.post_id ) LEFT JOIN wp_postmeta AS mt11 ON (wp_posts.ID = mt11.post_id AND mt11.meta_key = 'attribute_pa_connectivity' ) WHERE 1=1 AND wp_posts.post_parent = 2603 AND (
(
( wp_postmeta.meta_key = 'attribute_pa_workbee-size-drive' AND wp_postmeta.meta_value IN ('','') )
OR
mt1.post_id IS NULL
)
AND
(
( mt2.meta_key = 'attribute_pa_extrusion-colour' AND mt2.meta_value IN ('','') )
OR
mt3.post_id IS NULL
)
AND
(
( mt4.meta_key = 'attribute_pa_router' AND mt4.meta_value IN ('','') )
OR
mt5.post_id IS NULL
)
AND
(
( mt6.meta_key = 'attribute_pa_dust-shoe' AND mt6.meta_value IN ('','') )
OR
mt7.post_id IS NULL
)
AND
(
( mt8.meta_key = 'attribute_pa_cam-software' AND mt8.meta_value IN ('','') )
OR
mt9.post_id IS NULL
)
AND
(
( mt10.meta_key = 'attribute_pa_connectivity' AND mt10.meta_value IN ('','') )
OR
mt11.post_id IS NULL
)
) AND wp_posts.post_type = 'product_variation' AND ((wp_posts.post_status = 'publish')) GROUP BY wp_posts.ID ORDER BY wp_posts.menu_order ASC LIMIT 0, 1
Related
I have been trying to extract useful product feeds but there is still one attribute missing in the feed "image link"
Can anyone suggest me a tweak in the following query to make it perfect?
SELECT
`product`.`ID` AS `product_id`,
`product`.`post_title` AS `Title`,
`product`.`post_title` AS `Description`,
`product_price`.`meta_value` AS `Price`,
'no' AS `Identifier_exists`,
'Free' AS `Shipping`,
'in stock' AS `Availability`,
'new' AS `Condition`,
`product`.`guid` AS `Link`
FROM
(
(
(
`wp_posts` `product`
LEFT JOIN `wp_postmeta` `product_sku`
ON
(
(
`product`.`ID` = `product_sku`.`post_id`
)
)
)
LEFT JOIN `wp_postmeta` `product_price`
ON
(
(
`product`.`ID` = `product_price`.`post_id`
)
)
)
LEFT JOIN `wp_postmeta` `product_weight`
ON
(
(
`product`.`ID` = `product_weight`.`post_id`
)
)
)
WHERE
(
(
(`product`.`post_type` = 'product')
OR(`product`.`post_type` = 'product_variation')
) AND(`product_sku`.`meta_key` = '_sku') AND(
`product_price`.`meta_key` = '_price'
) AND(
`product_weight`.`meta_key` = '_weight'
)
)
ORDER BY
`product_id`
I have posts where the author is assigned as Co-Author. If i want to show them on my author page, they are not listed. Because of this condition in the query:
AND (wp_posts.post_author = 53)
How can i remove it? Or is there any better solution?
public static function pre_get_posts($query)
{
if ($query->is_author() && $query->is_main_query()):
$author = (get_query_var('author_name')) ? get_user_by('slug', get_query_var('author_name')) : get_userdata(get_query_var('author'));
$authorPostIDs = self::getAuthorsPostIDs($author->ID);
$coAuthorPostIDs = self::getCoAuthorsPostsIDs($author->ID);
$postIDs = array_unique(
array_merge($coAuthorPostIDs, $authorPostIDs), SORT_REGULAR
);
$query->set('post__in', $postIDs);
$query->set('post_status', 'publish');
endif;
}
My full query:
SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
WHERE 1=1
AND wp_posts.ID IN (349956,327745)
AND (wp_posts.post_author = 53)
AND wp_posts.post_type = 'post'
AND ((wp_posts.post_status = 'publish'))
ORDER BY wp_posts.post_date DESC
LIMIT 0, 10
I have used the below query to calculate the onhand quantity from InventTrans table but that onhand does not match with the AvailPhysical and/or PhysicalInvent of InventSum table. I have tried matching with other quantities as well but onhand is not matching. Please guide me what am i missing here
SELECT T1.ITEMID AS ITEMID
,T1.QTY
,T1.INVENTDIMID AS INVENTDIMID
,DATEDIFF(dd, T3.TRANSDATE, getdate()) AS Age
,t19.price as RetailPrice
,t1.CurrencyCode AS CurrencyKey
,T1.DATAAREAID AS DATAAREAID
,T1.PARTITION AS PARTITION
FROM INVENTTRANS T1
LEFT JOIN INVENTTRANSORIGIN T2 ON (
T1.INVENTTRANSORIGIN = T2.RECID
AND (T1.DATAAREAID = T2.DATAAREAID)
AND (T1.PARTITION = T2.PARTITION)
)
INNER JOIN INVENTTRANSPOSTING T3 ON (
(
(
(
T1.VOUCHERPHYSICAL = T3.VOUCHER
AND (T1.DATAAREAID = T3.DATAAREAID)
AND (T1.PARTITION = T3.PARTITION)
)
)
AND (
T1.DATEPHYSICAL = T3.TRANSDATE
AND (T1.DATAAREAID = T3.DATAAREAID)
AND (T1.PARTITION = T3.PARTITION)
)
)
AND (
T1.INVENTTRANSORIGIN = T3.INVENTTRANSORIGIN
AND (T2.DATAAREAID = T3.DATAAREAID)
AND (T2.PARTITION = T3.PARTITION)
)
) and t3.INVENTTRANSPOSTINGTYPE in (0)
LEFT JOIN INVENTDIM t4 ON (
t4.inventdimid = t1.inventdimid
AND t4.PARTITION = t1.PARTITION
AND t4.dataareaid = t1.dataareaid
)
LEFT OUTER JOIN INVENTTABLEMODULE T19 ON T19.ItemID = T1.ItemID AND T19.DataAreaID = T1.DataAreaID and T19.Partition = T1.Partition AND T19.MODULETYPE=0
LEFT OUTER JOIN INVENTTABLE T20 ON T1.ITEMID = T20.ITEMID AND T1.DATAAREAID = T20.DATAAREAID
where T20.ITEMTYPE <> 2
Any help would be greatly appreciated.
How do I write this "WHERE" condition in a way which is compatible with Doctrine?
( ( `translations_es_google`.`translation_date` < `translations_masters`.`translation_date` ) OR ( `translations_es_google`.`translation_date` is null ) )
What I have tried (unsuccessfully) are:
$query1
->andWhere('((t.translationDate < m.translationDate) OR (t.translationDate is NULL))');
$query1
->andWhere('(t.translationDate < m.translationDate) OR (t.translationDate is NULL)');
Table alias for the Doctrine query are
t represents the table translations_es_google
m represents the table translations_masters
When I remove this "andWhere" condition the rest of the QueryBuilder query executes as expected.
The query I am trying to execute is
SELECT
`translations_masters`.`translation_key` , `translations_masters`.`text_domain` , `translations_masters`.`translation_date`
FROM
`translations_masters`
LEFT JOIN
`translations_es_google` ON ( ( `translations_masters`.`text_domain` = `translations_es_google`.`text_domain` ) AND ( `translations_masters`.`translation_key` =`translations_es_google`.`translation_key` ) )
WHERE
`translations_masters`.`language_iso` NOT LIKE 'es-Google' AND ( ( `translations_es_google`.`translation_date` < `translations_masters`.`translation_date` ) OR ( `translations_es_google`.`translation_date` is null ) )
GROUP BY
`translations_masters`.`translation_key` , `translations_masters`.`text_domain`
ORDER BY
`translations_masters`.`translation_date` ASC
As requested the QueryBuilder version of this query is:
$query1 = $this->entityManager
->createQueryBuilder()
->select('m.textDomain , m.translationKey , m.translationDate , m.translationDate AS translationMasterDate , t.translationDate')
->from(
'AMDatabase\Entity\TheVerse\Translations' . $explode1 . $explode2,
't'
)
->leftJoin(
'AMDatabase\Entity\TheVerse\TranslationsMasters',
'm',
Join::WITH,
'(m.textDomain = t.textDomain) AND (m.translationKey = t.translationKey)'
)
->groupBy('m.textDomain , m.translationKey')
->orderBy(
'm.translationDate',
'ASC'
)
->setMaxResults('1');
$query1
->andWhere(
$query1->expr()
->notLike(
'm.languageIso',
':languageIso'
)
)
->setParameter(
'languageIso',
$value
);
$query1->andWhere(
$query1->expr()->orX(
't.translationDate < m.translationDate',
't.translationDate IS NULL'
)
);
$result1 = $query1->getQuery()
->getArrayResult();
The output of $query1->getQuery()->getSQL() is
SELECT
t0_.text_domain AS text_domain_0, t0_.translation_key AS translation_key_1, t0_.translation_date AS translation_date_2, t0_.translation_date AS translation_date_3, t1_.translation_date AS translation_date_4
FROM
thev1010_theverseoftheday.translations_es_google t1_
LEFT JOIN
thev1010_theverseoftheday.translations_masters t0_ ON ((t0_.text_domain = t1_.text_domain) AND (t0_.translation_key = t1_.translation_key))
WHERE
t0_.language_iso NOT LIKE ? AND (t1_.translation_date < t0_.translation_date OR t1_.translation_date IS NULL)
GROUP BY
t0_.text_domain, t0_.translation_key
ORDER BY
t0_.translation_date ASC
LIMIT 1
The ? value is 'es-Google'
The output of $query1->getQuery()->getDQL(); is
SELECT
m.textDomain , m.translationKey , m.translationDate , m.translationDate AS translationMasterDate , t.translationDate
FROM
AMDatabase\Entity\TheVerse\TranslationsEsGoogle t
LEFT JOIN
AMDatabase\Entity\TheVerse\TranslationsMasters m WITH (m.textDomain = t.textDomain) AND (m.translationKey = t.translationKey)
WHERE
m.languageIso NOT LIKE :languageIso AND (t.translationDate < m.translationDate OR t.translationDate IS NULL)
GROUP BY
m.textDomain , m.translationKey
ORDER BY
m.translationDate ASC
The ? value is 'es-Google'
How about orX expression?
You can try it this way:
$query1->andWhere(
$query1->expr()->orxX(
't.translationDate < m.translationDate',
't.translationDate IS NULL'
)
);
orX gives you the ability to add multiple conditions, separated by comma.
You can also separate your orX condition to its own variable and pass everything added to it to andWhere condition.
i have this ( huge ) sql query to convert into doctrine2 .
i already succeeded with createNativeQuery() but sometimes results don't match original one ( from mysql )
here is the query :
SELECT e1_.etapes AS etapes3, e1_.position AS position4, c0_.exercicesData_id AS Exercice_id, exo.titre as Exo, age.bornInf as ageInf, age.bornSup as ageSup, imc.bornInf as imcInf, imc.bornSup as imcSup, sexe.bornInf as sexeInf, sexe.bornSup as sexeSup
FROM ContrainteData c0_
LEFT JOIN ExerciceData e1_ ON c0_.exercicesData_id = e1_.id
LEFT JOIN Exercice exo ON e1_.exercice_id = exo.id
LEFT JOIN contraintedata_entrydata c3_ ON c0_.id = c3_.contraintedata_id
INNER JOIN (SELECT * FROM `entrydata` GROUP BY type_id, bornInf, bornSup) AS age ON age.type_id = 1
INNER JOIN (SELECT * FROM `entrydata` GROUP BY type_id, bornInf, bornSup) AS imc ON imc.type_id = 4
INNER JOIN (SELECT * FROM `entrydata` GROUP BY type_id, bornInf, bornSup) AS sexe ON sexe.type_id = 5
WHERE
( age.bornSup >= 30 and age.bornInf <= 30 ) and
( imc.bornSup >= 20 and imc.bornInf <= 20 ) and
( sexe.bornSup >= 1 and sexe.bornInf <= 1 ) and
e1_.entrainement_id = 6
GROUP BY etapes3, position4
ORDER BY etapes3 ASC, position4 ASC
with the queryBuilder , i have done the following :
$qb1 = $this->createQueryBuilder('c');
$qb2 = $this->createQueryBuilder('t');
$qb2->select( 't' )
->from ( 'bonk\AppBundle\Entity\EntryData', 'en' )
->groupBy( 'en.type')
->addGroupBy( 'en.bornInf' )
->addGroupBy( 'en.bornSup' );
$qb1->select( 'c' )
->leftJoin( 'c.exercicesData', 'e' )
->leftJoin( 'e.exercice' , 'ex' )
->join ( $qb2->getDql(), 'age', 'with', 'age.type = 1' )
->join ( $qb2->getQuery()->getDql(), 'imc', 'with', 'imc.type = 4' )
->join ( $qb2->getQuery()->getDql(), 'sexe', 'with', 'sexe.type = 5')
->where ( 'age.bornSup >= 30 and age.bornInf <= 30' )
->andWhere( 'imc.bornSup >= 20 and imc.bornInf <= 20' )
->andWhere( 'sexe.bornSup >= 1 and sexe.bornInf <= 1' )
->andWhere( 'e.entrainement = 6' )
->groupBy ( 'e.etapes', 'ASC' )
->addGroupBy( 'e.position', 'ASC' );
return $qb1->getQuery()->getArrayResult();
i have the following error :
"[Semantical Error] line 0, col 116 near 'SELECT t FROM': Error: Class 'SELECT' is not defined "
i finally succeed with a mysql view which is called by a fake entity in doctrine and DQL Query .
to create a view on sql , simply execute this line :
"create view VIEWNAME YOUQUERY"
in my example :
"create view entrydataView SELECT * FROM `entrydata` GROUP BY type_id, bornInf, bornSup"