otzy Posted December 11, 2010 Share Posted December 11, 2010 My database has more than 100000 products and more than 200000 images.In some cases page load time was 40sec. and moreI have found that problem is in JOIN that contains IF function in ON clause.This JOIN is located in function getProducts in /classes/Cart.phpIf you have the same perfomance problem you can change SELECT: $sql = ' SELECT cp.`id_product_attribute`, cp.`id_product`, cp.`quantity` AS cart_quantity, pl.`name`, pl.`description_short`, pl.`available_now`, pl.`available_later`, p.`id_product`, p.`id_category_default`, p.`id_supplier`, p.`id_manufacturer`, p.`id_tax`, p.`on_sale`, p.`ecotax`, p.`quantity`, p.`price`, p.`reduction_price`, p.`reduction_percent`, p.`reduction_from`, p.`reduction_to`, p.`weight`, p.`out_of_stock`, p.`active`, p.`date_add`, p.`date_upd`, t.`id_tax`, tl.`name` AS tax, t.`rate`, pa.`price` AS price_attribute, pa.`quantity` AS quantity_attribute, pa.`ecotax` AS ecotax_attr, #FIX CASE WHEN i1.id_image IS NULL THEN i2.id_image ELSE i1.id_image END AS id_image, (SELECT legend FROM `ps_image_lang` WHERE id_lang=1 AND id_image=(CASE WHEN i1.id_image IS NULL THEN i2.id_image ELSE i1.id_image END) LIMIT 1) as legend, # FIXED i.`id_image`, il.`legend`, pl.`link_rewrite`, cl.`link_rewrite` AS category, CONCAT(cp.`id_product`, cp.`id_product_attribute`) AS unique_id, IF (IFNULL(pa.`reference`, \'\') = \'\', p.`reference`, pa.`reference`) AS reference, IF (IFNULL(pa.`supplier_reference`, \'\') = \'\', p.`supplier_reference`, pa.`supplier_reference`) AS supplier_reference, (p.`weight`+ pa.`weight`) weight_attribute, IF (IFNULL(pa.`ean13`, \'\') = \'\', p.`ean13`, pa.`ean13`) AS ean13, pai.`id_image` AS \'pai_id_image\' FROM `'._DB_PREFIX_.'cart_product` cp LEFT JOIN `'._DB_PREFIX_.'product` p ON p.`id_product` = cp.`id_product` LEFT JOIN `'._DB_PREFIX_.'product_lang` pl ON (p.`id_product` = pl.`id_product` AND pl.`id_lang` = '.intval($this->id_lang).') LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON (pa.`id_product_attribute` = cp.`id_product_attribute`) LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = p.`id_tax`) LEFT JOIN `'._DB_PREFIX_.'tax_lang` tl ON (t.`id_tax` = tl.`id_tax` AND tl.`id_lang` = '.intval($this->id_lang).') LEFT JOIN `'._DB_PREFIX_.'product_attribute_image` pai ON (pai.`id_product_attribute` = pa.`id_product_attribute`) #FIX LEFT JOIN `ps_image` i1 ON (i1.id_image=pai.id_image AND i1.id_product=cp.id_product) LEFT JOIN `ps_image` i2 ON (i2.id_product=p.id_product AND i2.`cover`=1) /* FIXED LEFT JOIN `'._DB_PREFIX_.'image` i ON (IF(pai.`id_image`, i.`id_image` = (SELECT i2.`id_image` FROM `'._DB_PREFIX_.'image` i2 INNER JOIN `'._DB_PREFIX_.'product_attribute_image` pai2 ON (pai2.`id_image` = i2.`id_image`) WHERE i2.`id_product` = p.`id_product` AND pai2.`id_product_attribute` = pa.`id_product_attribute` ORDER BY i2.`position` LIMIT 1), i.`id_product` = p.`id_product` AND i.`cover` = 1) ) LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.intval($this->id_lang).') */ LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (p.`id_category_default` = cl.`id_category` AND cl.`id_lang` = '.intval($this->id_lang).') WHERE `id_cart` = '.intval($this->id).' '.($id_product ? ' AND cp.`id_product` = '.intval($id_product) : '').' AND p.`id_product` IS NOT NULL GROUP BY unique_id ORDER BY cp.date_add ASC'; 1 Link to comment Share on other sites More sharing options...
chrisxm Posted December 11, 2010 Share Posted December 11, 2010 Thanks for the tip Otzy ! Link to comment Share on other sites More sharing options...
otzy Posted December 12, 2010 Author Share Posted December 12, 2010 Thanks for the tip Otzy ! 4 hours of mining There is the same bug in v1.4 Link to comment Share on other sites More sharing options...
mecollectibles Posted April 12, 2011 Share Posted April 12, 2011 Would you please tell the line that should be checked & also the version of Prestashop? Link to comment Share on other sites More sharing options...
otzy Posted April 13, 2011 Author Share Posted April 13, 2011 classes/Cart.php - function getProducts (line 245 in PS 1.3.5.0, line 300 in PS 1..4) Link to comment Share on other sites More sharing options...
mecollectibles Posted April 13, 2011 Share Posted April 13, 2011 does it work with version 1.3.2 too? Link to comment Share on other sites More sharing options...
mecollectibles Posted April 13, 2011 Share Posted April 13, 2011 Your code is very complicated. You talk about a line to make 1 change but give the whole code & we should search to see exactly what different than our code to change & if that is not the fact, why all these lines brought?I think such bringing of many lines is not for here where most those refer are not specialists & not have much time too. If we wanted to search between all your lines, we were going to PHP classes to learn it & no need to come here then! ;-)))) Link to comment Share on other sites More sharing options...
mecollectibles Posted April 13, 2011 Share Posted April 13, 2011 I gave up. I do not think this advise is good. It just wasted my time compare all time to see the differences & the work seems so unprofessional that I doubt if I use it it will harm my website more! Link to comment Share on other sites More sharing options...
otzy Posted April 13, 2011 Author Share Posted April 13, 2011 This is SQL request. I cosider it has to be shown entirely in order to prevent errors while you will find where you must insert changed lines.The new lines of code are under the comment #FIX (two new fields and two new JOIN)Lines need to be removed are commented near the word FIXEDConcerning professionalismthis code: LEFT JOIN `'._DB_PREFIX_.'image` i ON (IF(pai.`id_image`,.... is unprofessional because it requires the full scan of huge tableI have replaced that JOIN with the new one on key fields: LEFT JOIN `ps_image` i1 ON (i1.id_image=pai.id_image AND i1.id_product=cp.id_product) LEFT JOIN `ps_image` i2 ON (i2.id_product=p.id_product AND i2.`cover`=1) Link to comment Share on other sites More sharing options...
otzy Posted April 13, 2011 Author Share Posted April 13, 2011 It just wasted my time compare all time to see the differences if you do not use versioning system try WinMerge to compare files. Link to comment Share on other sites More sharing options...
mecollectibles Posted April 13, 2011 Share Posted April 13, 2011 What helps beginners like me the usual way all programmers help that is like that:in line say 25 replace the following "the original text"with:"the suggested text"line say 28 immediately after this line:"the line in the file"add the following lines:"the suggested line(s)"It was really so strange I see your suggestion so long & then you advise of a software that takes time to learn how to work with while most questions in this forum are urgent. If we were to go learn software while our websites are crashed, our life time may end & we not learned the way to correct the mistakes on our websites.I have never seen such way in giving advise in Prestashop or oscommerce that I was using for a year & not seen in other software advises too. Really very strange. Link to comment Share on other sites More sharing options...
otzy Posted April 14, 2011 Author Share Posted April 14, 2011 You are right. But if you read carefully the first post, all you need is to replace query with the suggested one.But you wanted to find differences (and I supposed you are familiar with php and sql). That's why I have posted changed lines and link to WinMerge.So the single mistake I made in first post is the lack of Prestashop version. Link to comment Share on other sites More sharing options...
mecollectibles Posted May 4, 2011 Share Posted May 4, 2011 This is SQL request. I cosider it has to be shown entirely in order to prevent errors while you will find where you must insert changed lines.The new lines of code are under the comment #FIX (two new fields and two new JOIN)Lines need to be removed are commented near the word FIXEDConcerning professionalismthis code: LEFT JOIN `'._DB_PREFIX_.'image` i ON (IF(pai.`id_image`,.... is unprofessional because it requires the full scan of huge tableI have replaced that JOIN with the new one on key fields: LEFT JOIN `ps_image` i1 ON (i1.id_image=pai.id_image AND i1.id_product=cp.id_product) LEFT JOIN `ps_image` i2 ON (i2.id_product=p.id_product AND i2.`cover`=1) Let me see if I well understand it.I should chaned the whole lines below with the 2 lines you suggested?LEFT JOIN `'._DB_PREFIX_.'image` i ON (IF(pai.`id_image`, i.`id_image` = (SELECT i2.`id_image` FROM `'._DB_PREFIX_.'image` i2 INNER JOIN `'._DB_PREFIX_.'product_attribute_image` pai2 ON (pai2.`id_image` = i2.`id_image`) WHERE i2.`id_product` = p.`id_product` AND pai2.`id_product_attribute` = pa.`id_product_attribute` ORDER BY i2.`position` LIMIT 1), i.`id_product` = p.`id_product` AND i.`cover` = 1) ) Link to comment Share on other sites More sharing options...
otzy Posted May 4, 2011 Author Share Posted May 4, 2011 Let me see if I well understand it.I should chaned the whole lines below with the 2 lines you suggested?LEFT JOIN `'._DB_PREFIX_.'image` i ON (IF(pai.`id_image`, i.`id_image` = (SELECT i2.`id_image` FROM `'._DB_PREFIX_.'image` i2 INNER JOIN `'._DB_PREFIX_.'product_attribute_image` pai2 ON (pai2.`id_image` = i2.`id_image`) WHERE i2.`id_product` = p.`id_product` AND pai2.`id_product_attribute` = pa.`id_product_attribute` ORDER BY i2.`position` LIMIT 1), i.`id_product` = p.`id_product` AND i.`cover` = 1) ) this line has to be deleted too:LEFT JOIN `'._DB_PREFIX_.'image_lang` il ON (i.`id_image` = il.`id_image` AND il.`id_lang` = '.intval($this->id_lang).')and in addition you must change codei.`id_image`, il.`legend`, with this one: CASE WHEN i1.id_image IS NULL THEN i2.id_image ELSE i1.id_image END AS id_image, (SELECT legend FROM `ps_image_lang` WHERE id_lang=1 AND id_image=(CASE WHEN i1.id_image IS NULL THEN i2.id_image ELSE i1.id_image END) LIMIT 1) as legend, so it would be better if you will change the whole SQL expression Link to comment Share on other sites More sharing options...
mecollectibles Posted May 4, 2011 Share Posted May 4, 2011 so it would be better if you will change the whole SQL expressionI replaced the SQL with the one you supplied above but my website crashed & I had to remove it & restore the original. Link to comment Share on other sites More sharing options...
otzy Posted May 4, 2011 Author Share Posted May 4, 2011 what is your PS version?send me classes/Cart.php and I'll try to fix it. Link to comment Share on other sites More sharing options...
mecollectibles Posted May 4, 2011 Share Posted May 4, 2011 Version 1.3.2.3I attach the file. Cart.php Link to comment Share on other sites More sharing options...
otzy Posted May 4, 2011 Author Share Posted May 4, 2011 test attached file please.Check that errors are enabled in /config/config.inc.php <?php /* Debug only */ ini_set('display_errors', 'on'); define('_PS_DEBUG_SQL_', true); Cart.php Link to comment Share on other sites More sharing options...
mecollectibles Posted May 5, 2011 Share Posted May 5, 2011 I did as you suggested but I had one of my worst experiences in my website errors.I prefer to give up now & do not follow this post at all. I simply do not think this works for me. But thanks anyway. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now