Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql select with in子句不使用索引_Mysql_Indexing - Fatal编程技术网

Mysql select with in子句不使用索引

Mysql select with in子句不使用索引,mysql,indexing,Mysql,Indexing,我有一个联系人表,它的主键是id。它还有一个辅助索引idx_id_del_user(id,deleted,user_id) 下面的查询使用索引,因此速度非常快- select id from jts_contacts where id = '00000402-25c8-7375-e3df-4ec5b66de11d' and deleted = 0; 在0.0098s中获取1行 但是,当我使用in子句时,外部查询进入完整表扫描。我希望它使用主键或idx_id_del_用户 select * f

我有一个联系人表,它的主键是id。它还有一个辅助索引idx_id_del_user(id,deleted,user_id)

下面的查询使用索引,因此速度非常快-

select id
from jts_contacts
where id = '00000402-25c8-7375-e3df-4ec5b66de11d'
and deleted = 0;
在0.0098s中获取1行

但是,当我使用in子句时,外部查询进入完整表扫描。我希望它使用主键或idx_id_del_用户

select  *
from jts_contacts FORCE INDEX (idx_id_del_user)
where id in
(select id
from jts_contacts
where id = '00000402-25c8-7375-e3df-4ec5b66de11d')
and deleted = 0
9秒内取1行

说明计划-

id, select_type,          table,         type, possible_keys,                 key, key_len, ref, rows, Extra
------------------------------------------------------------------------------------
1, 'PRIMARY',            'jts_contacts', 'ALL', '',                           '',   '',     '', 1127275, 'Using where'
2, 'DEPENDENT SUBQUERY', 'jts_contacts', 'const', 'PRIMARY,idx_id_del_user', 'PRIMARY', '108', 'const', 1, 'Using index'
该表有120万条记录,并对该表进行了分析。我在没有强制索引选项的情况下尝试了它,但它仍然没有使用索引。对加快查询速度有什么建议吗



警告:使用联接而不是in子句将起作用,但是,由于这是从现有产品生成的查询,因此无法将其更改为使用联接。

据我所知,in将遍历所有匹配的记录,并将它们与子句中的值进行比较,每次一行


所以,你能做的最好的事情就是在
deleted
上使用索引,你只需要浏览
deleted=0

我刚刚遇到了同样的问题,在阅读了Marcus Adams的帖子后,我想到了一些我从运行表更新中学到的东西,基于同一个表中的数据:首先创建一个派生表,如下所示:

SELECT * FROM jts_contacts WHERE id IN
(SELECT id FROM
    (SELECT id FROM jts_contacts WHERE id = '00000402-25c8-7375-e3df-4ec5b66de11d')
temp)
AND deleted = 0
这将首先将内部查询的完整结果提取到派生的
temp
表中,然后在此基础上运行外部查询


这种模式将类似查询的速度从几分钟提高到不到一秒钟。我不骗你。

谢谢。我也试过了。然而,deleted只有两个值0和1(这不是很有选择性)。我实际上将响应时间增加到12秒。我同意这个答案,但是它不起作用,因为删除的索引不是很有选择性。