我有一位客户要求我调整他的MySQL数据库,以实现一些新功能并提高现有Web应用程序的性能。创建辅助表以提高大型MySQL表的性能?
最大的桌子(〜90 GB)拥有超过200M行,并且以定期间隔(每次访问他拥有的任何一个网站时都会有一次)增长。由于连续的INSERT,从后端页面执行的每个SELECT查询需要一段时间才能完成,因为每次都会重新生成索引。
我在我自己的服务器上从BTREE索引切换到HASH索引做了模拟。 SELECT和INSERT都没有运行得更快。该表使用MyISAM作为存储引擎。只有INSERT和SELECT,没有UPDATE或DELETE。
我想出了创建与每个INSERT一起更新的辅助表的想法,以加速来自后端的每个SELECT查询。我知道这是不好的做法,但是,我确信统计页面的表现会提高。
我不是一位数据库性能专家,因为您可能已经注意到了......是否有更好的方法呢?
顺便说一下,从phpMyAdmin我看到,表上的大多数索引都有0的基数。在我的模拟中,这没有发生。我不确定为什么会发生这种情况。
非常感谢。
第一次更新:我刚刚了解到,MyISAM引擎不支持散列索引。
第二次更新:好的。这是表格模式。
CREATE TABLE `visits` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`datetime` int(8) NOT NULL,
`webmaster_id` char(18) NOT NULL,
`country` char(2) NOT NULL,
`connection` varchar(15) NOT NULL,
`device` varchar(15) NOT NULL,
`provider` varchar(100) NOT NULL,
`ip_address` varchar(15) NOT NULL,
`url` varchar(300) NOT NULL,
`user_agent` varchar(300) NOT NULL,
PRIMARY KEY (`id`),
KEY `datetime` (`datetime`),
KEY `webmaster_id` (`webmaster_id`),
KEY `country` (`country`),
KEY `connection` (`connection`),
KEY `device` (`device`),
KEY `provider` (`provider`)
) ENGINE=InnoDB;
因此,而不是像执行查询select count(*) from visits where datetime=20140715 and device="ios"
,会不会是最好从select count from visits_stats where datetime=20140715 and device="ios"
获取呢?
如上所述,INSERT比SELECT更频繁,但我的客户希望提高用于检索聚合数据的后端的性能。使用我的方法,每次访问意味着一个INSERT和一个INSERT/UPDATE(或REPLACE),这会增加一个或多个计数器(我还没有确定visitor_stats表的模式,上面的查询只是一个例子)。
除此之外,我决定用某个外部表的合适ID替换一些字段。到目前为止,数据存储在像connection = cable,device = android等字符串中。我不确定这会如何影响性能。
再次感谢。
你为什么不发布查询,表和索引的定义以及执行计划,使这里的人真的可以试着帮你吗? –