MySQL性能问题/查询速度慢,数据量大
MySql 我有一个查询需要花费一些时间才能加载到一个表中,名为MySQL性能问题/查询速度慢,数据量大,mysql,query-optimization,Mysql,Query Optimization,MySql 我有一个查询需要花费一些时间才能加载到一个表中,名为impressionthat 大约有5700万行。下表定义: +-----------------+--------------+------+-----+ | Field | Type | Null | Key | +-----------------+--------------+------+-----+ | id | int(11) | NO | P
impression
that
大约有5700万行。下表定义:
+-----------------+--------------+------+-----+
| Field | Type | Null | Key |
+-----------------+--------------+------+-----+
| id | int(11) | NO | PRI |
| data_type | varchar(16) | NO | MUL |
| object_id | int(11) | YES | |
| user_id | int(11) | YES | |
| posted | timestamp | NO | MUL |
| lat | float | NO | |
| lng | float | NO | |
| region_id | int(11) | NO | |
+-----------------+--------------+------+-----+
表中的索引为:
+------------+------------+----------+--------------+-------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name |
+------------+------------+----------+--------------+-------------+
| impression | 0 | PRIMARY | 1 | id |
| impression | 1 | posted | 1 | posted |
| impression | 1 | oi_dt | 1 | data_type |
| impression | 1 | oi_dt | 2 | object_id |
+------------+------------+----------+--------------+-------------+
典型的select语句如下所示:
SELECT COUNT(`id`)
FROM `impression`
WHERE
posted BETWEEN DATE('2014-01-04') AND DATE('2014-06-01')
AND `data_type` = 'event'
AND `object_id` IN ('1', '2', '3', '4', '5', '8', ...)
…典型的记录如下所示(按上述模式的顺序):
此语句运行大约需要26秒,这就是问题所在
谎言这里是否可以采用任何解决方案来减少这一时间
低于现在的水平?理想情况下为<1秒
我愿意切换存储解决方案/等。。。在这一点上任何有帮助的事情。
非常感谢你的帮助
其他可能值得注意的事情:
- 该表正在使用InnoDB存储引擎
- 使用MySQL 5.5
- 服务器:运行CentOS 6的8Gb RAM(机架空间)
上有一个索引
,在数据类型
,对象id
上有一个复合索引
您应该使用EXPLAIN找出查询当前使用的索引。EXPLAIN还将告诉您它估计将检查多少行以生成结果集(它可能会检查更多行,而不是将其放入最终结果)
列应按以下顺序排列:
data\u type='event'
数据类型
,发布
上建立索引。试试看,然后用解释来确认。这取决于您提供的日期范围是否比对象id列表更具选择性
另请参见我的演示。MySQL通常在给定查询中每个表只使用一个索引。您在发布的
上有一个索引
,在数据类型
,对象id
上有一个复合索引
您应该使用EXPLAIN找出查询当前使用的索引。EXPLAIN还将告诉您它估计将检查多少行以生成结果集(它可能会检查更多行,而不是将其放入最终结果)
列应按以下顺序排列:
data\u type='event'
数据类型
,发布
上建立索引。试试看,然后用解释来确认。这取决于您提供的日期范围是否比对象id列表更具选择性
另请参阅我的演示。不确定这是否是一个可行的解决方案,但分区可能会加快速度。我有一个类似的印象表,并发现下面的帮助很大。不过,我主要是在当天查询
ALTER TABLE impression PARTITION BY RANGE(TO_DAYS(posted))(
PARTITION beforeToday VALUES LESS THAN(735725),
PARTITION today VALUES LESS THAN(735726),
PARTITION future VALUES LESS THAN MAXVALUE
);
这确实需要一些维护(必须经常更新以获得好处)。如果您希望查询范围更广,我认为需要更少的维护。不确定这对您来说是否是一个可行的解决方案,但分区可能会加快速度。我有一个类似的印象表,并发现下面的帮助很大。不过,我主要是在当天查询
ALTER TABLE impression PARTITION BY RANGE(TO_DAYS(posted))(
PARTITION beforeToday VALUES LESS THAN(735725),
PARTITION today VALUES LESS THAN(735726),
PARTITION future VALUES LESS THAN MAXVALUE
);
这确实需要一些维护(必须经常更新以获得好处)。如果您希望查询更广泛的范围,我认为需要较少的维护。Bill,感谢您的快速回复。我知道这不是我第一次在我的回答中看到你的脸:)比尔,谢谢你的快速回复。我知道这不是我第一次在我的回答中看到你的脸:)1。去掉in()1中的倒逗号。去掉in()中的倒逗号