+ -
当前位置:首页 → 问答吧 → MySQL where xxx in 不使用索引 查询很慢!!

MySQL where xxx in 不使用索引 查询很慢!!

时间:2011-07-17

来源:互联网

select *  from CJ_LS
where CX_BS IN (SELECT CX_BS FROM CJ_CX WHERE SCCJ_DM= 'xxxx')


CJ_LS表中有200多万条记录,CX_BS 上有索引,但是这个sql的执行计划是:
1        PRIMARY        CJ_LS        ALL                                        2111632        Using where
2        DEPENDENT SUBQUERY        CJ_CX        ref        PK_CJ_CX,IDX_CJ_CX_SCCJ_DM        IDX_CJ_CX_SCCJ_DM        15        const        1        Using where


CJ_LS表还是进行了全表扫描

我执行过 ANALYZE TABLE cj_ls 表分析,现在查询很慢,怎么才能使用cx_bs上的索引呢??

作者: edgar108   发布时间: 2011-07-17



QUOTE:原帖由 edgar108 于 2011-7-17 10:05 发表
select *  from CJ_LS
where CX_BS IN (SELECT CX_BS FROM CJ_CX WHERE SCCJ_DM= 'xxxx')


CJ_LS表中有200多万条记录,CX_BS 上有索引,但是这个sql的执行计划是:
1        PRIMARY        CJ_LS        ALL                                        2111632        Using where
2        DEPENDENT SUBQUERY        CJ_CX        ref        PK_CJ_CX,IDX_CJ_CX_SCCJ_DM        IDX_CJ_CX_SCCJ_DM        15        const        1        Using where


CJ_LS表还是进行了全表扫描

我执行过 ANALYZE TABLE cj_ls 表分析,现在查询很慢,怎么才能使用cx_bs上的索引呢??

首先改写SQL


select *  from CJ_LS
where CX_BS IN (SELECT CX_BS FROM CJ_CX WHERE SCCJ_DM= 'xxxx')

为:



SELECT *  FROM CJ_LS M
WHERE  EXISTS (SELECT 1 FROM CJ_CX  N WHERE N.SCCJ_DM= 'xxxx' AND M.CX_BS=N.CX_BS);


其次最好,SCCJ_DM字段上有索引,且其过滤性还不错;CX_BS上也有索引

作者: jinguanding   发布时间: 2011-07-17

你再把新的SQL执行计划贴出来看下 。。。。

作者: jinguanding   发布时间: 2011-07-17

EXPLAIN SELECT *  FROM CJ_LS M
WHERE  EXISTS (SELECT 1 FROM CJ_CX  N WHERE N.SCCJ_DM= 'xxxx' AND M.CX_BS=N.CX_BS);

执行 计划 :


1        PRIMARY        M        ALL                                        2154403        Using where
2        DEPENDENT SUBQUERY        N        ref        PK_CJ_CX,IDX_CJ_CX_SCCJ_DM        IDX_CJ_CX_SCCJ_DM        15        const        1        Using where

作者: edgar108   发布时间: 2011-07-17



QUOTE:原帖由 edgar108 于 2011-7-17 10:25 发表
EXPLAIN SELECT *  FROM CJ_LS M
WHERE  EXISTS (SELECT 1 FROM CJ_CX  N WHERE N.SCCJ_DM= 'xxxx' AND M.CX_BS=N.CX_BS);

执行 计划 :


1        PRIMARY        M        ALL                                        2154403        Using where
2        DEPENDENT SUBQUERY        N        ref        PK_CJ_CX,IDX_CJ_CX_SCCJ_DM        IDX_CJ_CX_SCCJ_DM        15        const        1        Using where

CJ_LS上的字段:CX_BS有索引嘛,以及其过滤性如何?

作者: jinguanding   发布时间: 2011-07-17

show create table cj_ls:

CREATE TABLE `cj_ls` (
  `BBHM` decimal(6,0) DEFAULT NULL,
  `CX_BS` varchar(32) DEFAULT NULL,
  `ZDJS_JG` decimal(16,2) DEFAULT NULL,
  `CC_JG` decimal(16,2) DEFAULT NULL,
  `SCPJ_JG` decimal(16,2) DEFAULT NULL,
  UNIQUE KEY `PK_CJ_LS` (`CX_BS`,`BBHM`),
  KEY `IDX_CJ_LS_CX_BS` (`CX_BS`),
  KEY `IDX_CJ_LS_CX_BS_BBHM` (`BBHM`)
) ENGINE=MyISAM DEFAULT CHARSET=gbk

有索引的

作者: edgar108   发布时间: 2011-07-17

show index from cj_ls

cj_ls        0        PK_CJ_LS        1        CX_BS        A        538600                        YES        BTREE       
cj_ls        0        PK_CJ_LS        2        BBHM        A        2154403                        YES        BTREE       
cj_ls        1        IDX_CJ_LS_CX_BS        1        CX_BS        A        538600                        YES        BTREE       
cj_ls        1        IDX_CJ_LS_CX_BS_BBHM        1        BBHM        A        21                        YES        BTREE

作者: edgar108   发布时间: 2011-07-17

为什么喜欢用in和exists, join是正道

SELECT m.*  
FROM CJ_LS M, CJ_CX N
where m.CX_BS = n.CX_BS
and N.SCCJ_DM= 'xxxx';

如果SCCJ_DM是唯一的,用
select *  from CJ_LS
where CX_BS = (SELECT CX_BS FROM CJ_CX WHERE SCCJ_DM= 'xxxx')

作者: kerlion   发布时间: 2011-07-17

恩! 执行计划变了

其实 执行的是 存储过程中的一个delete 语句:

delete from CJ_LS where CX_BS IN (SELECT CX_BS FROM CJ_CX WHERE SCCJ_DM= ver_sccj_dm);

通过 show processlist 看到 这个delete 很慢

如果写成join的形式,delete该怎么写呢? 谢谢了。。

作者: edgar108   发布时间: 2011-07-17