2014-09-22 132 views
1

問題:下面顯示的查詢速度慢,最小執行時間爲3.x秒,並且類別ID在「IN」子句中的執行時間增加了一分鐘。查詢優化以減少執行時間

QUERY:

explain SELECT a.* FROM 
label a 
INNER JOIN category_label c ON a.id = c.label_id 
INNER JOIN product_label p ON a.id = p.label_id 
INNER JOIN product p2 ON p.product_id = p2.id 
INNER JOIN category c2 ON p2.category_id = c2.id 
INNER JOIN category c3 ON (c2.lft BETWEEN c3.lft AND c3.rgt) 
INNER JOIN user u ON ((u.id = p2.user_id AND u.is_active = 1)) 
INNER JOIN country c4 ON (p2.country_id = c4.id) 
WHERE (c.category_id IN ('843', '848', '849', '853', '856', '858') AND a.is_filterable = 1 AND a.type <> "textarea" AND c2.rgt = (c2.lft + 1) AND c3.id IN ('843', '848', '849', '853', '856', '858') AND c4.id IN ('190') AND p2.status = 1) 
GROUP BY a.id 
ORDER BY a.sort_order 

查詢的解釋 -

*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: c4 
     type: const 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: const 
     rows: 1 
     Extra: Using index; Using temporary; Using filesort 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: c3 
     type: range 
possible_keys: PRIMARY,lft_rgt_inx 
      key: PRIMARY 
     key_len: 4 
      ref: NULL 
     rows: 6 
     Extra: Using where 
*************************** 3. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: c 
     type: range 
possible_keys: PRIMARY,label_id,category_id 
      key: PRIMARY 
     key_len: 4 
      ref: NULL 
     rows: 197 
     Extra: Using where; Using index; Using join buffer 
*************************** 4. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: a 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: c.label_id 
     rows: 1 
     Extra: Using where 

*************************** 5. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: p 
     type: ref 
possible_keys: product_id,label_id 
      key: label_id 
     key_len: 4 
      ref: c.label_id 
     rows: 3827 
     Extra: 
*************************** 6. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: p2 
     type: eq_ref 
possible_keys: PRIMARY,category_id,user_id,country_id 
      key: PRIMARY 
     key_len: 8 
      ref: p.product_id 
     rows: 1 
     Extra: Using where 
*************************** 7. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: c2 
     type: eq_ref 
possible_keys: PRIMARY,lft_rgt_inx 
      key: PRIMARY 
     key_len: 4 
      ref: p2.category_id 
     rows: 1 
     Extra: Using where 
*************************** 8. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: u 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: p2.user_id 
     rows: 1 
     Extra: Using where 


Show create table - 

`labelMaster` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    `type` varchar(50) NOT NULL COMMENT 'textbox, checkbox, selectbox, textarea', 
    `show_filter` tinyint(1) NOT NULL DEFAULT '1', 
    `select_all_level` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB 


CREATE TABLE `categoryMaster` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `parent_id` int(11) NOT NULL DEFAULT '0', 
    `lft` int(11) NOT NULL DEFAULT '0', 
    `rgt` int(11) NOT NULL DEFAULT '0', 
    `level` tinyint(4) NOT NULL DEFAULT '0', 
    `product_count` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `lft_rgt_inx` (`lft`,`rgt`), 
    KEY `parent_id` (`parent_id`) 
) ENGINE=InnoDB 


CREATE TABLE `productMaster` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    `category_id` int(11) NOT NULL, 
    `status` tinyint(1) NOT NULL DEFAULT '-1' , 
    `user_id` int(11) NOT NULL, 
    `label_value_ids` varchar (255), 
    `product_source_url` varchar(255) NOT NULL, 
    `country_id` int(4) NOT NULL, 
    `state_id` int(5) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `category_id` (`category_id`), 
    KEY `user_id` (`user_id`), 
    KEY `x_area_id` (`x_area_id`), 
    KEY `state_id` (`state_id`), 
    KEY `country_id` (`country_id`), 
    FULLTEXT KEY `name` (`name`), 
    FULLTEXT KEY `label_value_ids` (`label_value_ids`) 
) ENGINE=MyISAM 


CREATE TABLE `product_label` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `product_id` bigint(20) NOT NULL, 
    `label_id` int(11) NOT NULL, 
    `label_value` varchar(1200) DEFAULT NULL, 
    `category_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `product_id` (`product_id`), 
    KEY `category_id` (`category_id`), 
    KEY `label_id` (`label_id`) 
) ENGINE=InnoDB 

CREATE TABLE `label_values` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `label_id` int(11) NOT NULL, 
    `value` varchar(255) NOT NULL, 
    `sort_order` smallint(6) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`), 
    KEY `label_id` (`label_id`), 
    CONSTRAINT `label_values_ibfk_1` FOREIGN KEY (`label_id`) REFERENCES `label` (`id`) ON DELETE CASCADE 
) ENGINE=InnoDB 

CREATE TABLE `category_label` (
    `category_id` int(11) NOT NULL, 
    `label_id` int(11) NOT NULL, 
    `is_listview` tinyint(1) NOT NULL, 
    `sort_order` smallint(2) NOT NULL, 
    PRIMARY KEY (`category_id`,`label_id`), 
    KEY `label_id` (`label_id`), 
    KEY `category_id` (`category_id`) 
) ENGINE=MyISAM 

請建議我我如何可以重寫查詢,以減少執行時間,使網站快。

我試圖改變數據庫引擎。

請注意:查詢已經在使用緩存。

+0

category_label表在哪裏? – Mihai 2014-09-22 23:10:16

+0

@mihal我已更新帖子請再次看看 – Avinash 2014-09-23 09:52:01

回答

1

一些觀察:你用a.id分組,isn t a.id a primary key?in that case GROUP BY is unnecessary. Rearrange your WHERE conditions with the most restrictive conditions first,leave the IN conditions last.Just for one value you don't need IN use =. If the values are INT`,你不需要引號,mysql知道它們是數字,但是使用引號會帶來輕微的開銷。

WHERE a.is_filterable = 1 AND a.type <> "textarea" 
AND c2.rgt = (c2.lft + 1) 
AND c4.id =190 AND p2.status = 1 
AND c3.id IN (843, 848, 849, 853, 856, 858) 
AND c.category_id IN (843, 848, 849, 853, 856, 858) 

表標籤(你不有你的問題)增加

ALTER TABLE `label` add KEY (is_filterable,type) 
ALTER TABLE `label` add KEY (sort_order) 

表類別(你不有你的問題)添加這些索引

ALTER TABLE `category` add KEY (rgt) 
ALTER TABLE `category` add KEY (lft) 
ALTER TABLE `category` add KEY (lft,rgt) 

在桌面產品上(您沒有問題)添加索引

ALTER TABLE `product` add KEY (status) 

在用戶表(你不有你的問題)增加

ALTER TABLE `user` add KEY (id,is_active) 

這些指標會隨着結構最有用的上述WHERE condition.Let我知道它是如何goes.Make確定索引不在那裏。

+1

謝謝,我已經給所有屬性進行了索引到哪裏條款。 – Avinash 2014-09-27 04:15:16