Redundant price evaluation queries

Create issue
Issue #1179 resolved
Hynek Cernoch created an issue

I had problems with hundreds of useless queries, which can be easy limited.

1) Every price evaluation (product.prices.get_product_quantity_adjustments) makes two database queries {{{ First query: SELECT COUNT(*) FROM "product_price" WHERE (...some conditions...) Next query: SELECT ... FROM "product_price" WHERE (...the same conditions...) ORDER BY ... LIMIT 1

This source code is absurd: if qty_discounts.count() > 0: adjustments = qty_discounts.order_by(...)[0].adjustments(product) }}} Patch: {{{ --- product/prices.py.orig +++ product/prices.py @@ -9,14 +9,14 @@ expiresisnull=False, expireslt=datetime.date.today()).filter(quantity__lte=qty)

- adjustments = None

  • if qty_discounts.count() > 0:
  • Get the price with the quantity closest to the one specified without going over

  • adjustments = qty_discounts.order_by('price','-quantity', 'expires')[0].adjustments(product)

  • elif parent:
  • adjustments = get_product_quantity_adjustments(parent, qty=qty)
  • Get the price with the quantity closest to the one specified without going over

  • adjustments = qty_discounts.order_by('price','-quantity', 'expires')[:1]
  • if adjustments:
  • adjustments = adjustments[0].adjustments(product)
  • else:
  • adjustments = None # maybe the value "None" is better then "[]" for some usage later.
  • if parent:
  • adjustments = get_product_quantity_adjustments(parent, qty=qty)

    if not adjustments: adjustments = PriceAdjustmentCalc(None) }}}

2) A product search http://localhost:8000/search/?keywords=someting makes pairs of redundant queries for every found product. It is caused by redundant tag {% ifchanged %} in the file satchmo_store/shop/templates/shop/search.html {{{ {% ifchanged %}<li><a href="{{ product.get_absolute_url }}">... ..{{ product|discount_price:sale|currency}}</li>{% endifchanged %} The content of tag is everytimes changed because every product has its own URL. The price in {% ifchanged %} tag is evaluated two times

Solution: Remove ifchanged and endifchanged tags.

Demo, that content of "change" is really evaluated two times by Django: {% for product in results.products %} {% ifchanged %}{% cycle "one" "two" "three" "four" %} {{ product.get_absolute_url }} {% endfor %} Renders as two http://.... four http://... }}}

3) The prices of all items in cart are evaluated two times on every page. (Exapmle:Ten items in cart = twenty additional queries on each page.) It is caused by the main template {{{ satchmo_store/shop/templates/base.html lines {% if cart_count %} .... {% if cart.total %} - {{ cart|discount_cart_total:sale|currency }}{% endif %} {% endif %} The condition {% if cart.total %} makes 10 queries

better is: {% if not cart._is_empty %} - {{ cart|discount_cart_total:sale|currency }}{% endif %} }}} which calls only one query for the condition evaluation, but the whole is nested in {% if cart_count %} and the inner condition is pretty redundant. (Should it be distinguished as a special case with one gratis item in the cart? Probably no.)

Comments (2)

  1. Chris Moffitt repo owner

    Thanks for pointing these out. I've committed your suggestions. Feel free to point out any other ones.

  2. Log in to comment