2013-11-29 136 views
0

我們已經寫了如下的查詢,並在表上創建了合適的索引。 QUERY如何提高我的查詢性能?

SELECT ref_order_id, order_id, cams_ref_order_id 
FROM cart_entries_archive 
WHERE regular_price <> product_price 
AND ref_order_id >0 
AND cams_ref_order_id > 0; 

但查詢由於這一點,我們越來越負載尖峯執行全表掃描。

我們嘗試通過在where子句列上添加索引,但仍然執行全面掃描。如果可能,請重新編寫查詢。

查詢說明計劃

mysql> explain select ref_order_id,order_id,cams_ref_order_id from cart_entries_archive where regular_price <> product_price and ref_order_id >0 and cams_ref_order_id > 0; 
+----+-------------+----------------------+------+---------------+------+---------+------+---------+-------------+ 
| id | select_type | table    | type | possible_keys | key | key_len | ref | rows | Extra  | 
+----+-------------+----------------------+------+---------------+------+---------+------+---------+-------------+ 
| 1 | SIMPLE  | cart_entries_archive | ALL | NULL   | NULL | NULL | NULL | 6490560 | Using where | 
+----+-------------+----------------------+------+---------------+------+---------+------+---------+-------------+ 
1 row in set (0.00 sec) 

表結構:

mysql> show create table cart_entries_archive\G 
*************************** 1. row *************************** 
     Table: cart_entries_archive 
Create Table: CREATE TABLE `cart_entries_archive` (
    `row_mod` datetime DEFAULT NULL, 
    `row_create` datetime DEFAULT NULL, 
    `address_id` int(11) DEFAULT NULL, 
    `backorder_date` datetime DEFAULT NULL, 
    `cancelled_date` datetime DEFAULT NULL, 
    `cart_entry_id` int(11) NOT NULL, 
    `cart_id` int(11) NOT NULL, 
    `delivery_date` datetime DEFAULT NULL, 
    `delivery_method` varchar(100) COLLATE latin1_bin DEFAULT NULL, 
    `delivery_note` varchar(255) COLLATE latin1_bin DEFAULT NULL, 
    `discount_amount` decimal(8,2) DEFAULT '0.00', 
    `gift_message` varchar(255) COLLATE latin1_bin DEFAULT NULL, 
    `occasion` varchar(255) COLLATE latin1_bin DEFAULT NULL, 
    `order_date` datetime DEFAULT NULL, 
    `order_id` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `order_status` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `product_name` varchar(255) COLLATE latin1_bin DEFAULT NULL, 
    `product_extra` varchar(255) COLLATE latin1_bin DEFAULT NULL, 
    `product_price` decimal(8,2) DEFAULT '0.00', 
    `product_count` int(11) DEFAULT NULL, 
    `product_cost` decimal(8,2) DEFAULT '0.00', 
    `product_sku` varchar(100) COLLATE latin1_bin DEFAULT NULL, 
    `product_notes` varchar(255) COLLATE latin1_bin DEFAULT NULL, 
    `parent_product_sku` varchar(100) COLLATE latin1_bin DEFAULT NULL, 
    `returned_date` datetime DEFAULT NULL, 
    `release_date` datetime DEFAULT NULL, 
    `regular_price` decimal(8,2) DEFAULT '0.00', 
    `shipping_cost` decimal(8,2) DEFAULT '0.00', 
    `service_charge` decimal(8,2) DEFAULT '0.00', 
    `sku_option_name` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `sku_option_value` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_company` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_fname` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_lname` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_address` varchar(100) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_address2` varchar(100) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_city` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_country` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_province` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_postal_code` varchar(10) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_phone` varchar(20) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_phone_ext` varchar(10) COLLATE latin1_bin DEFAULT NULL, 
    `ship_tracking_number` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `status` varchar(20) COLLATE latin1_bin DEFAULT NULL, 
    `tax` decimal(8,2) DEFAULT '0.00', 
    `total_charge` decimal(8,2) DEFAULT '0.00', 
    `website_id` int(11) DEFAULT NULL, 
    `microsite_id` int(11) DEFAULT NULL, 
    `defer_reason` varchar(255) COLLATE latin1_bin DEFAULT NULL, 
    `defer_key` varchar(255) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_evening_phone` varchar(20) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_mobile_phone` varchar(20) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_email` varchar(100) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_title` varchar(10) COLLATE latin1_bin DEFAULT NULL, 
    `shipping_district` varchar(30) COLLATE latin1_bin DEFAULT NULL, 
    `location_type` varchar(20) COLLATE latin1_bin DEFAULT NULL, 
    `occasion_id` int(11) DEFAULT NULL, 
    `occasion_date` datetime DEFAULT NULL, 
    `occasion_do_remind` int(11) DEFAULT NULL, 
    `coupon_ref_source_id` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `delivery_date_verified` int(11) DEFAULT NULL, 
    `florist_peak_charge` float DEFAULT NULL, 
    `member_id` varchar(10) COLLATE latin1_bin DEFAULT NULL, 
    `delivery_location_code` varchar(10) COLLATE latin1_bin DEFAULT NULL, 
    `simply_iflora` int(11) DEFAULT NULL, 
    `rotation_weight` int(11) DEFAULT NULL, 
    `area_charge` decimal(8,2) DEFAULT NULL, 
    `cf_indicator` varchar(5) COLLATE latin1_bin DEFAULT NULL, 
    `category_id` varchar(10) COLLATE latin1_bin DEFAULT NULL, 
    `cms_note` varchar(255) COLLATE latin1_bin DEFAULT NULL, 
    `qas_queried` int(11) DEFAULT NULL, 
    `shipping_verified` int(11) DEFAULT NULL, 
    `occasion_event_name` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `push_date` datetime DEFAULT NULL, 
    `ref_order_id` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `relationship` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `std_delivery_id` int(11) DEFAULT NULL, 
    `opt_delivery_id` int(11) DEFAULT NULL, 
    `service_date` datetime DEFAULT NULL, 
    `parameters` varchar(1024) COLLATE latin1_bin DEFAULT NULL, 
    `order_type` varchar(32) COLLATE latin1_bin DEFAULT NULL, 
    `cams_ref_order_id` varchar(50) COLLATE latin1_bin DEFAULT NULL, 
    `membership_discount` decimal(8,2) DEFAULT NULL, 
    PRIMARY KEY (`cart_entry_id`), 
    UNIQUE KEY `idx_2204` (`cart_entry_id`,`cart_id`), 
    UNIQUE KEY `idx_2318` (`cart_entry_id`,`order_id`), 
    KEY `idx_1049` (`order_date`), 
    KEY `idx_726` (`cart_id`), 
    KEY `idx_840` (`order_id`), 
    KEY `idx_row_create` (`row_create`), 
    KEY `idx_1035` (`push_date`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin 
1 row in set (0.00 sec) 
+0

您在查詢中未使用任何KEY(主鍵,唯一鍵)。你的索引字段是什麼? – Damodaran

+0

我曾嘗試在列ref_order_id,cams_ref_order_id上使用主鍵和唯一鍵,但沒有更改掃描。 – user3048109

回答

0

你的where子句中使用了 「>」,而不是 「=」,使得它不太可能是一個指數將是有益的。該表中有多少行滿足ref_order_id> 0和cams_ref_order_id> 0的條件?如果這個比例很高,則表掃描可能是最快的方法。即使有10%的記錄符合該標準,這可能意味着RDBMS必須閱讀表格的每一頁。從

create index TMP001 on cart_entries_archive 
(ref_order_id, cams_ref_order_id, order_id, regular_price, product_price) 

字段where子句帶領指數和其他一切如下:

如果你希望它是「僅索引」,您可以添加以下指標。如果這是您關心的唯一查詢,並且維護索引的成本可以忽略不計,那麼創建它並完成。

+0

我會建議索引在列(regular_price,product_price)上,並將其他列(ref_order_id,cams_ref_order_id,order_id)作爲索引的附加屬性。 –