我们有一个在MySQL数据库中相当静态的数据集,但是读取时间很糟糕(甚至在查询列的索引时也是如此)。理论上说,由于行是随机存储的(或者有时按照插入顺序存储),所以磁盘头必须扫描以找到不同的行,即使它知道索引所在的位置,而不是仅依次读取它们。在MySQL中更改磁盘上的数据组织
是否有可能改变订单数据存储在磁盘上,以便它可以顺序读取?不幸的是,我们现在不能添加更多的RAM来缓存所有的查询。如果可以更改订单,我们可以在订单内定义订单吗?如在列中排序,如果第一列相同,则按另一列排序。
这可能与索引有关吗?
其他详细信息:非关系型单表数据库,包含1600万行,1 GB数据总量,512 MB内存,Ubuntu 12.04上带有标准硬盘驱动器的MariaDB 5.5.30。另外这是一个使用OpenVZ的,2虚拟机专用核心E5-2620 CPU 2Ghz的
创建语法:
CREATE TABLE `Events` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`provider` varchar(10) DEFAULT NULL,
`location` varchar(5) DEFAULT NULL,
`start_time` datetime DEFAULT NULL,
`end_time` datetime DEFAULT NULL,
`cost` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `provider` (`provider`),
KEY `location` (`location`),
KEY `start_time` (`start_time`),
KEY `end_time` (`end_time`),
KEY `cost` (`cost`)
) ENGINE=InnoDB AUTO_INCREMENT=02 DEFAULT CHARSET=utf8;
这需要很长的时间Select语句:
SELECT *
FROM `Events`
WHERE `Events`.start_time >= '2013-05-03 23:00:00' AND `Events`.start_time <= '2013-06-04 22:00:00' AND `FlightRoutes`.location = 'Chicago'
解释选择:
1 SIMPLE Events ref location,start_time location 18 const 3684 Using index condition; Using where
是的,它可能是随机磁盘I/O是你的问题;是的,有些事情可以用来重构磁盘上的数据。但是,在这样做之前,让我们检查一下您的查询是否使用了合适的索引;请显示表模式,查询及其执行计划:'SHOW CREATE TABLE foo','SELECT ...'和'EXPLAIN SELECT ...'。 – eggyal
非常感谢您的回答。上面添加了语法和更多信息。 – AC360
您的数据不是“随机”存储的,MySQL根据您的主键(“聚簇索引”)对数据进行排序。由于存储数据的文件碎片化,它可能会随机结束。从MySQL的角度来看,数据是通过'id'排序的 –