我遇到了MySQL查询的问题,因为我的拙见认为索引不能正常工作。
我有一个包含7个索引字段和3个数据blob的表。
CREATE TABLE IF NOT EXISTS `superstrat` (
`idStrategy` int(11) NOT NULL AUTO_INCREMENT,
`strategy_date` datetime NOT NULL,
`strategy_type` int(11) NOT NULL,
`strategy_supertype` int(11) NOT NULL,
`strategy_codes` varchar(40) NOT NULL,
`strategy_vols` blob NOT NULL,
`strategy_prices` blob NOT NULL,
`strategy_hedge` blob NOT NULL,
`strategy_neutrality` int(11) NOT NULL,
`strategy_valuation_model` int(11) NOT NULL,
`strategy_source` int(11) NOT NULL,
PRIMARY KEY (`idStrategy`),
UNIQUE KEY `strategy_date` (`strategy_date`,`strategy_type`,`strategy_supertype`,`strategy_codes`,`strategy_neutrality`,`strategy_valuation_model`,`strategy_source`),
KEY `strategy_date_2` (`strategy_date`),
KEY `strategy_type` (`strategy_type`),
KEY `strategy_supertype` (`strategy_supertype`),
KEY `strategy_codes` (`strategy_codes`),
KEY `strategy_neutrality` (`strategy_neutrality`),
KEY `strategy_valuation_model` (`strategy_valuation_model`),
KEY `strategy_source` (`strategy_source`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=888605 ;
我执行此查询但速度太慢
SELECT * FROM test_ter.superstrat WHERE strategy_date >= '2004-01-01' AND strategy_type='0'
AND strategy_supertype = '0' AND strategy_valuation_model='6'
AND strategy_source ='0' AND strategy_codes='10;' AND strategy_neutrality='2' LIMIT 0,5000;
原因是它仅对两个索引执行index_merge查询:strategy_type,strategy_codes:
1 SIMPLE superstrat index_merge strategy_date,strategy_date_2,strategy_type,strategy_supertype,strategy_codes,strategy_neutrality,strategy_valuation_model,strategy_source strategy_type,strategy_codes 4,42 6258 Using intersect(strategy_type,strategy_codes); Using where
如何强制index_merge在其他字段上,这里它将提取6258行而不是1.5k,当我的数据库已满时,需要60秒才能提取50000行,但我很确定它可以缩减为目标1.5k,我只是不知道如何。 USE INDEX和FORCE INDEX似乎不起作用。
答案 0 :(得分:1)
您的查询速度慢的原因是因为索引太多了。
当一段数据插入到mysql表中时,它被写入硬盘驱动器上的文件。 与生活和计算机中的所有内容一样,在较小的文件中查找相关数据比在较大的文件中查找更容易 - 因此,索引。 索引是在一个单独的物理文件中写入的,索引文件的点是它比数据文件小,因此 - 在索引文件中找到一些东西更快,一旦你在那里找到它,它会告诉你在数据文件中你的记录在哪里是
当你现在查看你的表时,你会注意到你如何索引每个可能的列,这是 - 好吧,坏。你需要清楚地思考如何帮助计算机帮助你。
现在,当选择性为100%时,指数是“最好的”。这意味着,如果您有100条记录并且索引了一列“idStrategy” - 那么您将拥有100个不同的索引值。所以,不同指数VALUES的数量除以行数=选择性(直言不讳)。
那么,这里的问题是,您可以使用哪个列来过滤掉最有效的数据集?
首先想到的是strategy_date
列。它被定义为唯一键,它的类型是日期时间,因此它在内部保存为4字节整数,这使得它成为BETWEEN类型搜索的理想候选者,并且这是从数据集中选择内容时将产生最大差异的列。
其他列(例如strategy_neutrality
等)不能有很多不同的值,因此它们对索引的选择较差,因此 - 您不必将它们编入索引。
这里有很多要补充的内容,不过我写的内容应该至少可以为你提供一些有关如何谷歌搜索不清楚的东西的见解。希望它有所帮助。
答案 1 :(得分:0)
我刚刚从MyISAM切换到InnoDB。
1 SIMPLE superstrat index_merge strategy_date,strategy_date_2,strategy_type,strategy_supertype,strategy_codes,strategy_neutrality,strategy_valuation_model,strategy_source strategy_type,strategy_codes,strategy_source,strategy_supertype,strategy_neutrality,strategy_valuation_model 4,42,4,4,4,4 1248 Using intersect(strategy_type,strategy_codes,strategy_source,strategy_supertype,strategy_neutrality,strategy_valuation_model); Using where