MySQL查询优化,主键索引未使用?

时间:2015-04-25 10:24:57

标签: mysql database

我们有很多这样的问题,但是每个查询都是独特的,所以这个问题就出现了。我有以下查询

Select * from tblretailerusers where (company_id=169 or company_id in (select id from tblretailercompany where multi_ret_id='169')) and ( id in (Select contact_person_1 from tbllocations where status=1 and (retailer_comp_id=169 or retailer_comp_id in (select id from tblretailercompany where multi_ret_id='169'))) OR id in(Select contact_person_2 from tbllocations where status=1 and (retailer_comp_id=169 or retailer_comp_id in (select id from tblretailercompany where multi_ret_id='169'))) ) and (last_login is not null )

它有三个表,零售商,他们的位置和他们的用户。标准用户信息。每个零售商都可以拥有子零售商,因此零售商表具有父零售商ID。目前每个表有大约6K记录,所有表都有主键作为自动增量,我知道它们也被索引。在用户表电子邮件字段中编制索引。

现在,此查询采用< 1秒即可,但现在客户希望找到“电子邮件ID以特定字母开头的用户,例如ab。一旦我将其添加到查询中,它就开始花费大约50-60秒。我创建了电子邮件索引字段,该字段不是唯一的,新查询看起来像

Select * from tblretailerusers where (company_id=169 or company_id in (select id from tblretailercompany where multi_ret_id='169')) and  ( id in (Select contact_person_1 from tbllocations where status=1 and (retailer_comp_id=169 or retailer_comp_id in (select id from tblretailercompany where multi_ret_id='169')))  OR      id in(Select contact_person_2 from tbllocations where status=1 and (retailer_comp_id=169 or retailer_comp_id in (select id from tblretailercompany where multi_ret_id='169'))) ) and (last_login is not null ) and email  REGEXP '^A|^B' 

我尝试在两个版本的查询中使用Explain,我注意到有趣的事实是在主表行中它没有显示possible_key的任何值,因为我们使用主键id在用户表中搜索以及我也有电子邮件索引字段。这是查询说明:

enter image description here

我尝试重新创建索引,当前我有索引,该索引在用户表中除主键之外的一个索引中使用ID,CompanyID和Email。我还在公司表上创建了索引,但没有加速。用户表是MyISAM。

我的另一个问题是,如何跳过子查询的子查询,因为您可以看到它在上面的查询中使用了三次。

编辑:我在查询中使用REGEXP的原因是,当我尝试Like 'A%'时,使用该选项的速度甚至很慢。

修改我只使用last_login is null代替last_login is not null进行测试,结果只需不到5秒。不是无效或不是无效吗?

1 个答案:

答案 0 :(得分:0)

而不是使用RegEx:

and email  REGEXP '^A|^B' 

...尝试一个简单的LIKE:

and (email like 'A%' or email like 'B%')

正则表达式对于这个相当小的比较来说有点沉重。喜欢可能要快得多。此外,我不希望优化器尝试解码正则表达式尝试执行的操作。但是,使用Like,它知道并且可能会使用您设置的索引。