为什么这些MySQL查询在看起来相当的情况下需要如此不同的处理时间?
下面是三个MySQL查询。第一个在一个查询中返回我要查找的所有内容,而第二个在两个查询中返回相同的聚合结果 我想知道为什么单个查询的运行时间要长2-100秒,而三个查询之间的处理时间似乎应该相等。有没有办法优化单个查询,使其与单个查询一样快速运行?在单个查询的WHERE语句中添加更多的OR并不会增加处理时间,但在某些情况下,我需要执行更多的OR,最终单个查询的速度将与运行十个单独查询的速度一样快 单个查询似乎在运行后会被缓存,第一次运行可能需要几分钟,而单个查询总是在同一时间段内完成 多列索引在这里会有很大的不同吗 值得注意的是,该表没有ID字段作为主索引。这是导致这种不受欢迎的行为的原因吗 在这里很难运行测试,因为表有一亿行,添加列和索引需要将近一天的时间 单一查询(4.2s) 等效聚合查询(每个查询0.8秒) 解释这些问题为什么这些MySQL查询在看起来相当的情况下需要如此不同的处理时间?,mysql,indexing,Mysql,Indexing,下面是三个MySQL查询。第一个在一个查询中返回我要查找的所有内容,而第二个在两个查询中返回相同的聚合结果 我想知道为什么单个查询的运行时间要长2-100秒,而三个查询之间的处理时间似乎应该相等。有没有办法优化单个查询,使其与单个查询一样快速运行?在单个查询的WHERE语句中添加更多的OR并不会增加处理时间,但在某些情况下,我需要执行更多的OR,最终单个查询的速度将与运行十个单独查询的速度一样快 单个查询似乎在运行后会被缓存,第一次运行可能需要几分钟,而单个查询总是在同一时间段内完成 多列索引在
id select_type table type possible_keys key key_len ref rows extra
1 SIMPLE staging_company_search range name_word_0,name_word_1 name_word_0 102 NULL 2197605 Using index condition; Using where
1 SIMPLE staging_company_search ref name_word_0,name_word_1 name_word_1 102 const 128 Using index condition; Using where
1 SIMPLE staging_company_search ref name_word_0,name_word_1 name_word_0 102 const 33 Using index condition; Using where
数据库架构
CREATE TABLE `staging_company_search` (
`name_id` int(11) unsigned NOT NULL DEFAULT '0',
`name_word_0` varchar(100) NOT NULL,
`name_word_1` varchar(100) NOT NULL,
KEY `name_id` (`name_id`),
KEY `name_word_0` (`name_word_0`),
KEY `name_word_1` (`name_word_1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
我认为这是因为MySQL处理索引时必须检查几个条件(“OR”)。这可以在“解释查询”中看到,第一个查询在返回结果之前需要检查更多的行 我相信两个小结果的结合应该会取得更好的效果。你能试试下面的吗
SELECT name_id
FROM staging_company_search
WHERE (name_word_0 = 'the' AND name_word_1 = 'glazier')
UNION ALL
SELECT name_id
FROM staging_company_search
WHERE (name_word_0 = 'bridgewaters' AND name_word_1 = '');
在第一个查询中使用OR子句会破坏索引的使用。MySQL那样有点傻。它正在做一个完整的表格扫描:查看每一行。您最好只使用联合在一起的查询
要使您的查询和仅查询更快,请在
(name\u word\u 0,name\u word\u 1,name\u id)
上创建一个复合索引。通过对该索引的随机访问可以完全满足您的查询,并且应该在2兆行表中运行亚秒。这是因为mysql对简单查询只使用一个索引
如果在多个索引之间有选择,MySQL通常使用
查找最小行数(选择性最高)的索引
索引)
然而,mysql可以并且将使用两个索引,从版本5.0到。不幸的是,这种情况并不总是发生,即使发生了,也会产生结果
第一个explain输出显示索引合并优化没有在查询中与OR子句一起使用。它只使用name\u word\u 0上的索引
name_word_0非常适合,其中name_word_0='the'和name_word_1='glazier'代码>但正如第三个解释的输出所示,它根本不适合中的name\u word\u 0='bridgewaters'和name\u word\u 1=''代码>
因此,组合查询的速度非常慢。您可以通过创建一个跨越name_word_0和name_word_1的复合索引来克服这一问题。我注意到你的钥匙很长。您可以创建一个部分索引,并可能进一步加快速度
CREATE INDEX word01 ON staging_company_search (name_word_0(20), name_word_1(20))
如果在第一个查询中尝试(‘the’、‘glazier’、(‘bridgewaters’、“”))中的(name_word_0、name_word_1)位置,会发生什么?甚至更慢。该查询还包含稍微不同的逻辑,结果是四个name_单词的组合,而不是两个。我明白了。两个等价的聚合查询的并集如何?解释计划是否显示了这两者之间的差异?我添加了解释结果。它们非常不同,但我不确定如何解释原因,或者如何调整以进行补偿。您可以尝试在单个查询中使用下面的where代码,看看它是否比我更快,然后我可以在您的表模式中回答y更快,其中(name_id>0和name_word_0='the'和name_word_1='glazier'),或者(name_id>0 name_word_0='bridgewaters'和name_word_1='');
SELECT name_id
FROM staging_company_search
WHERE (name_word_0 = 'the' AND name_word_1 = 'glazier')
UNION ALL
SELECT name_id
FROM staging_company_search
WHERE (name_word_0 = 'bridgewaters' AND name_word_1 = '');
CREATE INDEX word01 ON staging_company_search (name_word_0(20), name_word_1(20))