我有一个简单的SQL查询,我正在尝试优化以删除“使用where;使用临时;使用filesort”。
这是表格:
CREATE TABLE `special_offers` (
`so_id` int(11) NOT NULL auto_increment,
`so_lid` int(11) NOT NULL,
`so_product_id` int(11) NOT NULL,
`so_bonus_product` int(11) NOT NULL,
`so_reverse_relate` tinyint(1) NOT NULL default '0',
`so_discount_amount` varchar(6) NOT NULL,
`so_start` date NOT NULL default '0000-00-00',
`so_expiry` date NOT NULL default '0000-00-00',
`so_active` tinyint(1) NOT NULL,
`so_archived` tinyint(4) NOT NULL default '0',
`so_added` datetime NOT NULL,
PRIMARY KEY (`so_id`),
KEY `so_archived` (`so_archived`),
KEY `so_active` (`so_active`),
KEY `so_start` (`so_start`),
KEY `so_expiry` (`so_expiry`),
KEY `so_product_id` (`so_product_id`),
KEY `so_bonus_product` (`so_bonus_product`),
KEY `so_lid` (`so_lid`)
) ENGINE=MyISAM AUTO_INCREMENT=65610 DEFAULT CHARSET=latin1
这是查询:
SELECT `so_id` , `so_lid` , `so_bonus_product` , `so_product_id`
FROM `special_offers`
WHERE `so_archived` = '0'
AND `so_active` = '1'
AND (
`so_start` <= CURDATE( )
OR `so_start` = '0000-00-00'
)
AND (
`so_expiry` >= CURDATE( )
OR `so_expiry` = '0000-00-00'
)
GROUP BY `so_lid`
解析:
mysql> EXPLAIN SELECT `so_id` , `so_lid` , `so_bonus_product` , `so_product_id` FROM `special_offers` WHERE `so_archived` = '0' AND `so_active` = '1' AND ( `so_start` <= CURDATE( ) OR `so_start` = '0000-00-00' ) AND ( `so_expiry` >= CURDATE( ) OR `so_expiry` = '0000-00-00' ) GROUP BY `so_lid`;
+----+-------------+-------------------+------+------------------------------------------+-------------+---------+-------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------------+------+------------------------------------------+-------------+---------+-------+------+----------------------------------------------+
| 1 | SIMPLE | special_offers | ref | so_archived,so_active,so_start,so_expiry | so_archived | 1 | const | 7684 | Using where; Using temporary; Using filesort |
+----+-------------+-------------------+------+------------------------------------------+-------------+---------+-------+------+----------------------------------------------+
答案 0 :(得分:2)
在(so_archived, so_active, so_lid, so_start, so_end)
答案 1 :(得分:0)
答案 2 :(得分:0)
我有一个综合索引(so_archived,so_active,so_lid)并添加一个关键字......
SELECT STRAIGHT_JOIN ...查询的其余部分
SELECT STRAIGHT_JOIN
`so_id` , `so_lid` , `so_bonus_product` , `so_product_id`
FROM
`special_offers`
WHERE
`so_archived` = '0'
AND `so_active` = '1'
AND ( `so_start` <= CURDATE( ) OR `so_start` = '0000-00-00' )
AND ( `so_expiry` >= CURDATE( ) OR `so_expiry` = '0000-00-00' )
GROUP BY
`so_lid`
答案 3 :(得分:0)
我认为小组可能会给你带来麻烦。
SELECT `so_id` , `so_lid` , `so_bonus_product` , `so_product_id` ... GROUP BY `so_lid`
按so_lid
进行分组时,so_id
,so_bonus_product
,so_product_id
的值对于给定的so_lid
都是相同的。您可能会发现意外结果。这也可能导致优化问题。
请参阅此文章。 http://dev.mysql.com/tech-resources/articles/debunking-group-by-myths.html