问题:下面显示的查询速度很慢,最小执行时间是3.x秒,而且“IN”子句中的类别ID增加,查询执行时间超过一分钟。
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 :(得分: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条件的结构最有用。让我知道它是怎么回事。确保索引不在那里。