表结构如下:
CREATE TABLE `crm_member` (
`member_id` int(11) NOT NULL AUTO_INCREMENT,
`shop_id` int(11) NOT NULL,
`nick` varchar(255) NOT NULL DEFAULT '',
`name` varchar(255) NOT NULL DEFAULT '',
`mobile` varchar(255) NOT NULL DEFAULT '',
`grade` int(11) NOT NULL DEFAULT '-1',
`trade_count` int(11) NOT NULL,
`trade_amount` float NOT NULL,
`last_trade_time` int(11) NOT NULL,
`trade_from` tinyint(4) NOT NULL,
`avg_price` float NOT NULL,
`seller_flag` tinyint(1) NOT NULL,
`is_black` tinyint(1) NOT NULL DEFAULT '0',
`created` int(11) NOT NULL,
PRIMARY KEY (`member_id`),
UNIQUE KEY `shop_id` (`shop_id`,`nick`),
KEY `last_trade_time` (`last_trade_time`),
KEY `idx_shop_id_grade` (`shop_id`,`grade`),
KEY `idx_shopid_created` (`shop_id`,`created`),
KEY `idx_trade_amount` (`shop_id`,`trade_amount`),
KEY `idx_trade_count` (`shop_id`,`trade_count`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
该表在shop_id 3498706下具有2148037行;
我的查询就像
SELECT AVG(trade_count) as trade_count, AVG(trade_amount) as trade_amount, AVG(grade) as grade from `crm_member_0141` WHERE shop_id = '3498706' and grade >= 0 and trade_count > 0 and is_black = 0 LIMIT 1
查询执行大约30秒。
解释结果
mysql> explain SELECT member_id, AVG(trade_count) as trade_count, AVG(trade_amount) as trade_amount, AVG(grade) as grade from `crm_member_0141` WHERE shop_id = 3498706 and grade >= 0 and trade_count > 0 and is_black = 0 order by member_id LIMIT 1;
+----+-------------+-----------------+------------+------+-------------------------------------------------------------------------------+---------+---------+-------+---------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------------+------------+------+-------------------------------------------------------------------------------+---------+---------+-------+---------+----------+-------------+
| 1 | SIMPLE | crm_member_0141 | NULL | ref | shop_id,idx_shop_id_grade,idx_shopid_created,idx_trade_amount,idx_trade_count | shop_id | 4 | const | 1074018 | 1.11 | Using where |
+----+-------------+-----------------+------------+------+-------------------------------------------------------------------------------+---------+---------+-------+---------+----------+-------------+
如何加快查询速度?
答案 0 :(得分:1)
尽管shop_id, grade
可能会加快行的选择速度,但看起来mysql选择使用主键而不是shop_id, grade
索引。
您可以使用USE INDEX
指令告诉mysql使用特定的索引进行查询:
尝试在表名后的查询中添加USE INDEX (idx_shop_id_grade)
,以查看计算是否更快。
否则,如果此查询特别有用并且经常在您的应用中调用,则可以为此查询构建更专业的索引:
您的查询选择shop_id
和is_black
的特定值,然后对grade
和trade_count
进行范围选择。
我建议尝试使用shop_id, is_black, grade, trade_count
进行索引。
注意:显然,首先要在测试数据库上进行测试