表结构是
CREATE TABLE `NewTable` (
`id` bigint(11) UNSIGNED NOT NULL AUTO_INCREMENT ,
`channel_id` int(11) UNSIGNED NOT NULL ,
`get_at` datetime NOT NULL ,
`value` double NOT NULL ,
PRIMARY KEY (`id`),
INDEX `get_at` USING BTREE (`get_at`) ,
INDEX `IX_avg` USING BTREE (`channel_id`, `get_at`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=latin1 COLLATE=latin1_swedish_ci
AUTO_INCREMENT=82861956
ROW_FORMAT=COMPACT;
八千万条数据
其中,经常用到select avg(value) from NewTable where channel_id in(aa,bb,cc) and get_at between 'YYYY-MM-DD H:mm:ss' and 'YYYY-MM-DD H:mm:ss'这种查询,现有如上两个索引,查询效率很慢,求教各位大神如何优化?
CREATE TABLE `NewTable` (
`id` bigint(11) UNSIGNED NOT NULL AUTO_INCREMENT ,
`channel_id` int(11) UNSIGNED NOT NULL ,
`get_at` datetime NOT NULL ,
`value` double NOT NULL ,
PRIMARY KEY (`id`),
INDEX `get_at` USING BTREE (`get_at`) ,
INDEX `IX_avg` USING BTREE (`channel_id`, `get_at`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=latin1 COLLATE=latin1_swedish_ci
AUTO_INCREMENT=82861956
ROW_FORMAT=COMPACT;
八千万条数据
其中,经常用到select avg(value) from NewTable where channel_id in(aa,bb,cc) and get_at between 'YYYY-MM-DD H:mm:ss' and 'YYYY-MM-DD H:mm:ss'这种查询,现有如上两个索引,查询效率很慢,求教各位大神如何优化?
现在执行一次查询大概要1分钟多,这个速度有点不能接收,谢谢版主~
explain select avg(value) from NewTable where channel_id in(aa,bb,cc) and get_at between 'YYYY-MM-DD H:mm:ss' and 'YYYY-MM-DD H:mm:ss'以供分析。
select avg(value) from NewTable FORCE INDEX(`IX_avg`) where channel_id in(aa,bb,cc) and get_at between 'YYYY-MM-DD H:mm:ss' and 'YYYY-MM-DD H:mm:ss'
mysql> explain select avg(value) from data where channel_id in (58,74,90,106) and get_at between '2012-8-26 17:25:07' and '2013-5-5 15:09:25';
+----+-------------+-------+-------+---------------+--------+---------+------+----------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+--------+---------+------+----------+-------------+
| 1 | SIMPLE | data | range | IX_avg | IX_avg | 12 | NULL | 10185390 | Using where |
+----+-------------+-------+-------+---------------+--------+---------+------+----------+-------------+
1 row in set
mysql> show index from data;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| data | 0 | PRIMARY | 1 | id | A | 83246361 | NULL | NULL | | BTREE | |
| data | 1 | IX_avg | 1 | channel_id | A | 18 | NULL | NULL | | BTREE | |
| data | 1 | IX_avg | 2 | get_at | A | 83246361 | NULL | NULL | | BTREE | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
3 rows in set
WHERE
channel_id IN(58,74,90,106) AND get_at BETWEEN '2012-8-26 17:25:07' AND '2013-5-5 15:09:25';贴结果
WHERE
channel_id IN(58,74,90,106) AND get_at BETWEEN '2012-8-26 17:25:07' AND '2013-5-5 15:09:25';
执行速度如何?
from (
select sum(value) as s,count(*) as c from data where channel_id in =58 and get_at between '2012-8-26 17:25:07' and '2013-5-5 15:09:25'
union all
select sum(value) as s,count(*) as c from data where channel_id in =74 and get_at between '2012-8-26 17:25:07' and '2013-5-5 15:09:25'
union all
select sum(value) as s,count(*) as c from data where channel_id in =90 and get_at between '2012-8-26 17:25:07' and '2013-5-5 15:09:25'
union all
select sum(value) as s,count(*) as c from data where channel_id in =106 and get_at between '2012-8-26 17:25:07' and '2013-5-5 15:09:25'
) t
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE data range IX_avg IX_avg 12 null 10284684 Using where另外直接执行SELECT * FROM NewTable
WHERE
channel_id IN(58,74,90,106) AND get_at BETWEEN '2012-8-26 17:25:07' AND '2013-5-5 15:09:25';速度也很慢,四分钟了还没执行完: (
建议新增1个字段INT型,建立索引,保存UNIX_TIMESTAMP(get_at)
新字段 BETWEEN FROM_UNIXTIME('2012-8-26 17:25:07') AND
FROM_UNIXTIME('2013-5-5 15:09:25')
alter table NewTable add index (get_at,channelid,value)
那当然不是...把EXPLAIN的结果贴出来啊。否则别人只能猜啊。
那当然不是...把EXPLAIN的结果贴出来啊。否则别人只能猜啊。悲剧,我在删除掉一个索引,然后重新建了一个新的索引之后,就访问不到原来的数据库了,现在只能访问那个服务器上的information_schema数据库,如果想访问原来的数据库的话会出现"access denied for user 'username'@'%' to database 'databasename'"的提示,而我show grants 的话却是"grant usage on *.* to 'username'@'%' identified by password 'xxxxxxxxx'"的提示,这是为什么,该怎么办啊,囧囧囧