CartMetrix - Do you know yours?

10/23/2006

MySQL Database Performance - ZenCart Sales Report

One of my client's ZenCart installs was loading the server down so much to generate sales reports with the Sales Report v1 contribution that the public side was noticeably less responsive for the couple of minutes it took to build the report. The site has been running for over three years and contains 9k orders, so there is a lot of data to weed through even for a weekly report. A quick look at the slow query log listed the following query as the culprit:

SELECT count( op.products_id ) AS attr_cnt, o.orders_id, opa.orders_products_id, opa.products_options, opa.products_options_values, opa.options_values_price, opa.price_prefix
FROM orders_products_attributes opa, orders o, orders_products op
WHERE o.orders_id = opa.orders_id
AND op.orders_products_id = opa.orders_products_id
AND o.date_purchased >= '2006-10-18T00:00:00'
AND o.date_purchased < '2006-10-19T00:00:00'
AND op.products_id =179
GROUP BY products_options_values
ORDER BY orders_products_id;

Running this query through EXPLAIN shows 20978 rows examined. In this case, thats 20978 rows per day included in the sales report.

The main problem with this query is the ORDER BY clause which cannot utilize an exisiting index. Adding the following index:

ALTER TABLE 'orders_products_attributes' ADD INDEX ( 'orders_products_id' )

limits the rows examined for each query to 68 (results).

This simple change allows the sales report to load in seconds as opposed to minutes with no noticeable lag on the public side.

The create table SQL for the current version of ZenCart (v1.3.5) contains the following index in orders_products_attributes:

...
KEY idx_orders_id_prod_id_zen (orders_id,orders_products_id)
...

This index is used in the query in question. In my tests it was only slightly slower than the single column index above. EXPLAIN showed about 270 rows examined with the two column index on my dataset while the single column index only examined 68 rows.

Popularity: 19%

10/20/2006

ZenCart Products ID Search

The ZenCart admin does not allow searching for products by the products_id field. This is the field assigned internally to each product as it is entered by ZenCart itself.

Using the Paypal Session Viewer (updated v2 here) to debug recent Paypal issues for a client, only shows the products_id ordered without any additional product information. To make it easy to find the product in the ZenCart admin from only the products_id make the following hack in admin/includes/modules/category_product_listing.php around line #191:

Before:

if (isset($_GET['search'])) {
      $products_query_raw = ("select p.products_type, p.products_id, pd.products_name, p.products_quantity,
                                       p.products_image, p.products_price, p.products_date_added,
                                       p.products_last_modified, p.products_date_available,
                                       p.products_status, p2c.categories_id,
                                       p.products_model,
                                       p.products_quantity_order_min, p.products_quantity_order_units, p.products_priced_by_attribute,
                                       p.product_is_free, p.product_is_call, p.products_quantity_mixed,
                                       p.products_quantity_order_max, p.products_sort_order
                                from "
. TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd, "
                                       . TABLE_PRODUCTS_TO_CATEGORIES . " p2c
                                where p.products_id = pd.products_id
                                and pd.language_id = '"
. (int)$_SESSION['languages_id'] . "'
                                and p.products_id = p2c.products_id
                                and (
                                pd.products_name like '%"
. zen_db_input($_GET['search']) . "%'
                                or pd.products_description like '%"
. zen_db_input($_GET['search']) . "%'
                                or p.products_model like '%"
. zen_db_input($_GET['search']) . "%')" .
                                $order_by);
    } else {

After:

if (isset($_GET['search'])) {
      $products_query_raw = ("select p.products_type, p.products_id, pd.products_name, p.products_quantity,
                                       p.products_image, p.products_price, p.products_date_added,
                                       p.products_last_modified, p.products_date_available,
                                       p.products_status, p2c.categories_id,
                                       p.products_model,
                                       p.products_quantity_order_min, p.products_quantity_order_units, p.products_priced_by_attribute,
                                       p.product_is_free, p.product_is_call, p.products_quantity_mixed,
                                       p.products_quantity_order_max, p.products_sort_order
                                from "
. TABLE_PRODUCTS . " p, " . TABLE_PRODUCTS_DESCRIPTION . " pd, "
                                       . TABLE_PRODUCTS_TO_CATEGORIES . " p2c
                                where p.products_id = pd.products_id
                                and pd.language_id = '"
. (int)$_SESSION['languages_id'] . "'
                                and p.products_id = p2c.products_id
                                and (
                                pd.products_name like '%"
. zen_db_input($_GET['search']) . "%'
                                or pd.products_description like '%"
. zen_db_input($_GET['search']) . "%'
                                or p.products_id = '"
. zen_db_input($_GET['search']) . "'
                                or p.products_model like '%"
. zen_db_input($_GET['search']) . "%')" .
                                $order_by);
    } else {

You can see the:

or p.products_id = '" . zen_db_input($_GET['search']) . "'

added near the bottom of the snippet.

Popularity: 15%

10/5/2006

ZenCart Godaddy and cURL

I recently migrated a customer's ZenCart site to a hosting account with Godaddy.com. The project went smoothly except for the Authorize.net gateway. Trying to process orders, the site timed out on the final order process page.

Godaddy's support site, some googling and debugging led to this working code to be added to the cURL routine in authorizenet_aim.php.

curl_setopt ($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
// The line below was posted on Godaddy's support site,
// but did not work for me
//curl_setopt ($ch, CURLOPT_PROXY,"http://64.202.165.130:3128");
// This line worked for me instead
curl_setopt ($ch, CURLOPT_PROXY,"64.202.165.130:3128");
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt ($ch, CURLOPT_TIMEOUT, 45);

Links:

Popularity: 36%


damonparker.org is proudly powered by WordPress
Entries (RSS) and Comments (RSS).

copyright © 2002-2008 damonparker.org. all rights reserved.

Close
E-mail It