Domanda

Please help me to rewrite the below query.

we are getting performance issues due to below query.in this query we are using sub-queries. please help me to re write without sub-query.

query is:

select 
    sum(a.order_count)
from
    (select 
        count(cart_id) as order_count, user_id
    from
        carts_archive
    where
        order_date > '2013-01-21 00:00:01'
            and user_id is not null
    group by user_id
    order by order_count desc) a
where
    a.order_count > 1;

we are not able to retrive explain plan also.

Explain plan:

explain plan :

+----+-------------+---------------+-------+--------------------------------------------+------------------------+---------+------+---------+----------------------------------------------+
| id | select_type | table         | type  | possible_keys                              | key                    | key_len | ref  | rows    | Extra                                        |
+----+-------------+---------------+-------+--------------------------------------------+------------------------+---------+------+---------+----------------------------------------------+
|  1 | PRIMARY     | <derived2>    | ALL   | NULL                                       | NULL                   | NULL    | NULL | 1436430 | Using where                                  |
|  2 | DERIVED     | carts_archive | range | nk_cart_ach_user_id,pk_cart_ach_order_date | pk_cart_ach_order_date | 9       | NULL | 3552006 | Using where; Using temporary; Using filesort |
+----+-------------+---------------+-------+--------------------------------------------+------------------------+---------+------+---------+----------------------------------------------+
2 rows in set (2 min 50.33 sec)

Table structure:

mysql> show create table carts_archive\G
*************************** 1. row ***************************
       Table: carts_archive
Create Table: CREATE TABLE `carts_archive` (
  `row_mod` datetime DEFAULT NULL,
  `row_create` datetime DEFAULT NULL,
  `order_date` datetime DEFAULT NULL,
  `billing_zip` varchar(10) COLLATE latin1_bin DEFAULT NULL,
  `billing_address` varchar(200) COLLATE latin1_bin DEFAULT NULL,
  `billing_home_phone` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `billing_email` varchar(100) COLLATE latin1_bin DEFAULT NULL,
  `status` varchar(30) COLLATE latin1_bin DEFAULT NULL,
  `website_id` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `discount_program` varchar(20) COLLATE latin1_bin DEFAULT NULL,
  `credit_card_exp_year` varchar(4) COLLATE latin1_bin DEFAULT NULL,
  `billing_country` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `add_client_flag` varchar(1) COLLATE latin1_bin DEFAULT NULL,
  `billing_last_name` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `billing_work_phone` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `total_charge` float(10,2) DEFAULT NULL,
  `add_newsletter_flag` varchar(1) COLLATE latin1_bin DEFAULT NULL,
  `cart_id` int(11) DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
  `discount_first_name` varchar(20) COLLATE latin1_bin DEFAULT NULL,
  `markcode` int(11) DEFAULT NULL,
  `discount_account_junk` varchar(20) COLLATE latin1_bin DEFAULT NULL,
  `gift_cert_junk` varchar(30) COLLATE latin1_bin DEFAULT NULL,
  `credit_card_name` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `billing_work_phone_ext` varchar(10) COLLATE latin1_bin DEFAULT NULL,
  `billing_state` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `billing_first_name` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `order_id` varchar(30) COLLATE latin1_bin DEFAULT NULL,
  `discount_last_name` varchar(20) COLLATE latin1_bin DEFAULT NULL,
  `credit_card_exp_month` varchar(2) COLLATE latin1_bin DEFAULT NULL,
  `credit_card_number` varchar(20) COLLATE latin1_bin DEFAULT NULL,
  `billing_city` varchar(100) COLLATE latin1_bin DEFAULT NULL,
  `credit_card_type` varchar(20) COLLATE latin1_bin DEFAULT NULL,
  `discount_account` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `asnbuyer` varchar(70) COLLATE latin1_bin DEFAULT NULL,
  `buyercookie` varchar(70) COLLATE latin1_bin DEFAULT NULL,
  `expire_date` datetime DEFAULT NULL,
  `security_string` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `user_information` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `track_id` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `gift_cert` varchar(255) COLLATE latin1_bin DEFAULT NULL,
  `billing_address2` varchar(100) COLLATE latin1_bin DEFAULT NULL,
  `visited_signup` varchar(1) COLLATE latin1_bin DEFAULT NULL,
  `paypal_email_junk` varchar(127) COLLATE latin1_bin DEFAULT NULL,
  `used_saved_cc_flag` varchar(1) COLLATE latin1_bin DEFAULT NULL,
  `paypal_auth_amount_junk` float DEFAULT NULL,
  `bml_auth_code_junk` varchar(20) COLLATE latin1_bin DEFAULT NULL,
  `bml_approve_amount_junk` float DEFAULT NULL,
  `bml_account_id_junk` varchar(30) COLLATE latin1_bin DEFAULT NULL,
  `bml_order_number_junk` varchar(22) COLLATE latin1_bin DEFAULT NULL,
  `alt_reference_num` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `alt_account_id` varchar(200) COLLATE latin1_bin DEFAULT NULL,
  `alt_approval_amount` float DEFAULT NULL,
  `alt_points_used` float DEFAULT NULL,
  `alt_auth_id` varchar(30) COLLATE latin1_bin DEFAULT NULL,
  `alt_redemption_rate` float DEFAULT NULL,
  `cvv_response_code` varchar(50) COLLATE latin1_bin DEFAULT NULL,
  `cvv_indicator_value` varchar(1) COLLATE latin1_bin DEFAULT NULL,
  `language_id` varchar(10) COLLATE latin1_bin DEFAULT 'ENUS',
  `gc_trans_id` varchar(20) COLLATE latin1_bin DEFAULT NULL,
  `gc_auth_date` datetime DEFAULT NULL,
  `gc_pin` varchar(20) COLLATE latin1_bin DEFAULT NULL,
  `gift_cert_value` float DEFAULT NULL,
  UNIQUE KEY `pk_cart_ach_cart_id` (`cart_id`),
  KEY `nk_cart_ach_user_id` (`user_id`),
  KEY `pk_cart_ach_order_date` (`order_date`),
  KEY `carts_archive_n1` (`row_mod`),
  KEY `order_id_n1` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin
1 row in set (0.00 sec)
È stato utile?

Soluzione 2

Try creating index as below and then see EXPLAIN plan

CREATE INDEX idx_order_date_user_id ON carts_archive(order_date,user_id);

Altri suggerimenti

i don't see any use of having order by clause in your subquery. information about number of records in table with indexes on them will help, or explain plan will help.

also try with this slightly modified sql below

select sum(a.order_count) from (select count(cart_id) as order_count, user_id from carts_archive where order_date > '2013-01-21 00:00:01' and user_id is not null group by user_id having count(card_id)>1) a

my knowledge about this issue is limited but oce when we had a similar issue i found that SQL SERVER 2012 dosent have automated indexing or some issues related to indexing when its not specifies, so add a primary key or any sort of index ,without proper indexing orderby may have performance issues

refer this too SQL Server 2012 Performance Issue

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top