Problem/Motivation

DB select are very slow on huge DB

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Comments

targoo created an issue. See original summary.

targoo’s picture

StatusFileSize
new2 KB

Split the main query into multiple ones.

bojanz’s picture

Can you do an EXPLAIN of the query in question? A query like this should always be fast, we might be missing an index?

adaddinsane’s picture

Status: Active » Patch (to be ported)

Patch looks good. Ordering ensures the latest matching order number comes first.

@bojanz: We have a 50Gig table so, yes, it's slow. We don't need you to merge this patch into the branch but we need it for composer to apply it into the deployed code.

bojanz’s picture

Status: Patch (to be ported) » Needs review

There is no porting to be done here.

Anyway, waiting on the EXPLAIN.

rszrama’s picture

Title: Slow queries » Improve performance of cart order ID selection for anonymous users
Version: 7.x-1.4 » 7.x-1.x-dev
Category: Bug report » Task
targoo’s picture

We are going to update the description and provide more details. We just needed that patch asap.

Status: Needs review » Needs work

The last submitted patch, 2: slow_queries-2632550-2.patch, failed testing.

rszrama’s picture

Good deal; I understand - I've posted patches to the queue to use in drush make before as well. : )

rszrama’s picture

fwiw, patch looked good to me on initial review. I think the test fails might be unrelated.

targoo’s picture

Thanks rszrama. Yeah we kind of needed that patch urgently since we needed to hotfix our boxes.

We will probably provide a clean up patch if this considered to be merged.

Will get the EXPLAIN asap.

rszrama’s picture

Status: Needs work » Needs review
smccabe’s picture

Status: Needs review » Needs work

This query just needs an proper index as bojan suspected.

MariaDB [eikon]> explain SELECT order_id FROM commerce_order WHERE order_id IN (1,2,3,4,5) AND uid = 0 AND status IN (1, 2) ORDER BY order_id DESC;
+------+-------------+----------------+------+---------------+------+---------+-------+------+-------------+
| id   | select_type | table          | type | possible_keys | key  | key_len | ref   | rows | Extra       |
+------+-------------+----------------+------+---------------+------+---------+-------+------+-------------+
|    1 | SIMPLE      | commerce_order | ref  | PRIMARY,uid   | uid  | 4       | const |    5 | Using where |
+------+-------------+----------------+------+---------------+------+---------+-------+------+-------------+

MariaDB [eikon]> show indexes in commerce_order;
+----------------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table          | Non_unique | Key_name     | Seq_in_index | Column_name  | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| commerce_order |          0 | PRIMARY      |            1 | order_id     | A         |      314899 |     NULL | NULL   |      | BTREE      |         |               |
| commerce_order |          0 | order_number |            1 | order_number | A         |      314899 |     NULL | NULL   | YES  | BTREE      |         |               |
| commerce_order |          0 | revision_id  |            1 | revision_id  | A         |      314899 |     NULL | NULL   | YES  | BTREE      |         |               |
| commerce_order |          1 | uid          |            1 | uid          | A         |       62979 |     NULL | NULL   |      | BTREE      |         |               |
+----------------+------------+--------------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

Ideally a specific index of order_id, uid and status, in that order.

smccabe’s picture

Status: Needs work » Needs review
StatusFileSize
new1.21 KB
travis-bradbury’s picture

Status: Needs review » Reviewed & tested by the community
StatusFileSize
new1.22 KB
new497 bytes

I don't have anything to replicate the original slow query (mine seem to be fast anyway since I either don't have or don't have many anonymous orders) but I do see a dramatic before and after when filtering by status. Query time for admin/commerce/orders with an exposed filter for order status went from 503.85 ms to 1.38ms.

Before:

MariaDB> EXPLAIN SELECT order_id FROM commerce_order WHERE order_id IN (1,2,3,4,5) AND uid = 0 AND status IN (1, 2) ORDER BY order_id DESC;
+------+-------------+----------------+------+---------------+------+---------+-------+------+-------------+
| id   | select_type | table          | type | possible_keys | key  | key_len | ref   | rows | Extra       |
+------+-------------+----------------+------+---------------+------+---------+-------+------+-------------+
|    1 | SIMPLE      | commerce_order | ref  | PRIMARY,uid   | uid  | 4       | const |    5 | Using where |
+------+-------------+----------------+------+---------------+------+---------+-------+------+-------------+

After:

mysql> EXPLAIN SELECT order_id FROM commerce_order WHERE order_id IN (1,2,3,4,5) AND uid = 0 AND status IN (1, 2) ORDER BY order_id DESC;
+----+-------------+----------------+------------+-------+----------------------------------------+---------------------+---------+------+------+----------+--------------------------+
| id | select_type | table          | partitions | type  | possible_keys                          | key                 | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+----------------+------------+-------+----------------------------------------+---------------------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | commerce_order | NULL       | range | PRIMARY,uid,status,order_id_uid_status | order_id_uid_status | 8       | NULL |    5 |    20.00 | Using where; Using index |
+----+-------------+----------------+------------+-------+----------------------------------------+---------------------+---------+------+------+----------+--------------------------+

This new patch is just a teeny change to the update description: fixing a typo, adding a period, and changing how the table name is written to match previous update descriptions.

torgospizza’s picture

I can confirm that the patch in #15 makes queries such as select order_id, status from commerce_order where created < :time and status in ('cart', 'checkout_checkout', 'checkout_review') limit 20 much faster. (This is a query we run in Cron to expire very old orders.)

Let's please get this in soon. Thanks!

rszrama’s picture

Status: Reviewed & tested by the community » Fixed

Thanks guys! Committed.

  • rszrama committed 7cabffc on 7.x-1.x authored by smccabe
    Issue #2632550 by tbradbury, smccabe, bojanz, torgosPizza: Improve...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.