LemonStand Forum: ActiveRecord Category Page Suggestions - LemonStand Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

ActiveRecord Category Page Suggestions

#1 User is offline   activeholdingco 

  • Member
  • PipPipPip
  • Group: Members
  • Posts: 177
  • Joined: 23-September 10

Posted 19 April 2011 - 12:02 PM

Hello LS,

Right now I use a simple Shop_Product::find_products call on my category page. In that function you query the DB to get the IDs and then do this for each one:

			$result_array = array();
			if (count($product_ids))
			{
				foreach ($product_ids as $id)
					$result_array[] = Shop_Product::create()->find($id);

				$result = new Db_DataCollection($result_array);
			}
			else
				$result = new Db_DataCollection(array());


Since we already know all the ids that we will be checking why not do something like Shop_Product::create()->find(array($ofIDs)) or Shop_Product::create->find_bulk($id);

The problem I have with the current implementation is that it results in 40+ queries that look like this:
[2011-04-19   19:46:05] SELECT (pages.url) as page_url, (0) as items_ordered, (if (shop_products.grouped = 1,  concat(shop_products.name,  " (",  shop_products.grouped_option_desc, ")"),  shop_products.name)) as grouped_name, (page_calculated_join.title) as page_calculated, (product_type_calculated_join.name) as product_type_calculated, (manufacturer_link_calculated_join.name) as manufacturer_link_calculated, (select group_concat(db_files.name ORDER BY 1 SEPARATOR ',  ') from db_files where
							db_files.master_object_id = shop_products.id and (master_object_class='Shop_Product' and field='images')) as images_calculated, (tax_class_calculated_join.name) as tax_class_calculated, (select group_concat(shop_categories.name ORDER BY 1 SEPARATOR ',  ') from shop_categories,  shop_products_categories where
							shop_categories.id=shop_products_categories.shop_category_id and
							shop_products_categories.shop_product_id=shop_products.id) as categories_calculated, (select group_concat(shop_products.grouped_option_desc ORDER BY 1 SEPARATOR ',  ') from shop_products where
							shop_products.product_id = shop_products.id) as grouped_products_all_calculated, (select group_concat(shop_custom_attributes.name ORDER BY 1 SEPARATOR ',  ') from shop_custom_attributes where
							shop_custom_attributes.product_id = shop_products.id) as options_calculated, (select group_concat(shop_extra_options.description ORDER BY 1 SEPARATOR ',  ') from shop_extra_options where
							shop_extra_options.product_id = shop_products.id and ((option_in_set is null or option_in_set=0))) as product_extra_options_calculated, (select group_concat(shop_extra_option_sets.name ORDER BY 1 SEPARATOR ',  ') from shop_extra_option_sets,  shop_products_extra_sets where
							shop_extra_option_sets.id=shop_products_extra_sets.extra_option_set_id and
							shop_products_extra_sets.extra_product_id=shop_products.id) as extra_option_sets_calculated, (select group_concat(shop_tier_prices.id ORDER BY 1 SEPARATOR ',  ') from shop_tier_prices where
							shop_tier_prices.product_id = shop_products.id) as price_tiers_calculated, (select group_concat(shop_products.name ORDER BY 1 SEPARATOR ',  ') from shop_products,  shop_related_products where
							shop_products.id=shop_related_products.related_product_id and
							shop_related_products.master_product_id=shop_products.id) as related_products_all_calculated, (select group_concat(shop_product_properties.name ORDER BY 1 SEPARATOR ',  ') from shop_product_properties where
							shop_product_properties.product_id = shop_products.id) as properties_calculated, (select group_concat(db_files.name ORDER BY 1 SEPARATOR ',  ') from db_files where
							db_files.master_object_id = shop_products.id and (master_object_class='Shop_Product' and field='files')) as files_calculated, (select group_concat(shop_customer_groups.name ORDER BY 1 SEPARATOR ',  ') from shop_customer_groups,  shop_products_customer_groups where
							shop_customer_groups.id=shop_products_customer_groups.customer_group_id and
							shop_products_customer_groups.shop_product_id=shop_products.id) as customer_groups_calculated, (select trim(concat(ifnull(lastName,  ''),  ' ',  ifnull(concat(substring(firstName,  1,  1),  '. '),  ''),  ifnull(concat(substring(middleName,  1,  1),  '.'),  ''))) from users where users.id=shop_products.updated_user_id) as updated_user_name, (trim(ifnull((select trim(concat(ifnull(lastName,  ''),  ' ',  ifnull(concat(substring(firstName,  1,  1),  '. '),  ''),  ifnull(concat(substring(middleName,  1,  1),  '.'),  ''))) from users where users.id=shop_products.created_user_id),  ''))) as created_user_name, shop_products.* FROM shop_products LEFT JOIN pages ON shop_products.page_id=pages.id
LEFT JOIN pages as page_calculated_join ON page_calculated_join.id = shop_products.page_id
LEFT JOIN shop_product_types as product_type_calculated_join ON product_type_calculated_join.id = shop_products.product_type_id
LEFT JOIN shop_manufacturers as manufacturer_link_calculated_join ON manufacturer_link_calculated_join.id = shop_products.manufacturer_id 
LEFT JOIN shop_tax_classes as tax_class_calculated_join ON tax_class_calculated_join.id = shop_products.tax_class_id
 WHERE
	 (shop_products.id = '22465')  LIMIT 0, 1


Ignoring the complex query just take a look at the end. Why not make it so that we can create objects in bulk if we already know the ids that results in a query that looks like this instead:

 WHERE
	 (shop_products.id IN ('22465', '22465'))  LIMIT 0, 1


That would eliminate 40 queries for me on each page.

Not to mention the same thing for images:

SELECT (concat(lastName,  " ",  firstName)) as user_name, (trim(ifnull((select trim(concat(ifnull(lastName,  ''),  ' ',  ifnull(concat(substring(firstName,  1,  1),  '. '),  ''),  ifnull(concat(substring(middleName,  1,  1),  '.'),  ''))) from users where users.id=db_files.created_user_id),  ''))) as created_user_name, db_files.* FROM db_files LEFT JOIN users ON users.id=db_files.created_user_id
 WHERE
	 (db_files.master_object_id = '21447')  AND (db_files.master_object_class='Shop_Product' and field='images') ORDER BY
	sort_order, id


 WHERE
	 (db_files.master_object_id IN ('21447', '21447'))


Would result in another 40+ query savings. Right now with a large catalog doing searching is taking me quite a bit of page load due to the number of queries needed to execute this really slows down my site.

Thanks!
0

#2 User is offline   Aleksey 

  • Co-Founder
  • Group: +Administrators
  • Posts: 3,633
  • Joined: 31-October 09

Posted 21 April 2011 - 02:55 PM

Hi! We will look into it soon. Thanks!

#3 User is offline   Aleksey 

  • Co-Founder
  • Group: +Administrators
  • Posts: 3,633
  • Joined: 31-October 09

Posted 18 May 2011 - 09:56 PM

Hi!

We just published the update which replaces the multiple queries with a single query.

Thanks!

Share this topic:


Page 1 of 1

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users