MySQL查询速度慢除了使用索引?
我正在运行一个查询,以查找与同一表中的其他行关联的行(特别是那些具有相同MySQL查询速度慢除了使用索引?,mysql,indexing,subquery,Mysql,Indexing,Subquery,我正在运行一个查询,以查找与同一表中的其他行关联的行(特别是那些具有相同ddef索引的行,也称为。除svar之外的所有非空列都是相同的)。查询速度很慢,我不明白为什么 下表: CREATE TABLE `data_der_testing` ( `def` VARCHAR( 30 ) NOT NULL , `cntry` VARCHAR( 5 ) NOT NULL , `var` VARCHA
ddef
索引的行,也称为。除svar
之外的所有非空列都是相同的)。查询速度很慢,我不明白为什么
下表:
CREATE TABLE `data_der_testing` (
`def` VARCHAR( 30 ) NOT NULL ,
`cntry` VARCHAR( 5 ) NOT NULL ,
`var` VARCHAR( 10 ) NOT NULL ,
`type` VARCHAR( 4 ) NOT NULL ,
`svar` VARCHAR( 5 ) NOT NULL ,
`track` INT ( 3 ) NOT NULL ,
`year` INT ( 5 ) NOT NULL ,
`v1211` TEXT,
`v1212` TEXT,
`v1302` TEXT,
`v1304` TEXT,
`v1305` TEXT,
INDEX ddef ( `cntry`, `var`, `type`, `track`, `year` ),
UNIQUE ( `def` ),
UNIQUE idb ( `cntry`, `var`, `type`, `svar`, `track`, `year` )
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
表中的数据由约450k行组成:
`def`: a combination of all other "NOT NULL" columns, which makes it unique
`cntry`: 34 country codes
`var`: 86 variable codes
`type`: 2 type codes
`svar`: 3 sub-variable codes
`track`: 6 codes
`year`: 32 year codes (99, 1980...2010)
`v...`: the variable value I want to check and update if needed
显示索引的输出:
data_der 1 ddef 1 cntry A 410 BTREE
data_der 1 ddef 2 var A 18871 BTREE
data_der 1 ddef 3 type A 33388 BTREE
data_der 1 ddef 4 track A 43404 BTREE
data_der 1 ddef 5 year A 434048 BTREE
查询:
SELECT *
FROM `data_der`
WHERE `type`='str' && `svar` != '99' &&`v1305` = '-90' && ROW(`cntry`,`var`,`type`,`track`,`year`) IN
(
SELECT `cntry`,`var`,`type`,`track`,`year`
FROM `data_der`
WHERE `type` = 'str' && `svar` != '99' && `v1305` != '-90'
GROUP BY `cntry`,`var`,`type`,`track`,`year`
)
这就是解释:
1 PRIMARY data_der ALL 434048 Using where
2 DEPENDENT SUBQUERY data_der index ddef 71 6 Using where
如果你对如何使这个问题对普通观众更有用有什么建议,请告诉我。我从其他问题中获益匪浅,很乐意为大家做贡献
最好的
Chonez基于评论(Thx,people!),我编写了以下连接,我将使用它进行更新:
UPDATE `data_der`
SET `v1305` = '-95'
WHERE `def` IN
(
SELECT * FROM
(
SELECT
t1.`def`
FROM `data_der` AS t1
JOIN `data_der` AS t2
ON (t1.`cntry`,t1.`var`,t1.`type`,t1.`track`,t1.`year`) = (t2.`cntry`,t2.`var`,t2.`type`,t2.`track`,t2.`year`)
WHERE
t1.`type` = 'str'
&& t1.`svar` != '99'
&& t1.`v1305` = '-90'
&& t2.`v1305` != '-90'
) AS sub
)
以及子查询的解释:
1 SIMPLE t1 ref idb,sdef,cntry,var,type,track,year,ddef type 14 const 65338 Using where
1 SIMPLE t2 ref idb,sdef,cntry,var,type,track,year,ddef ddef 71 impic.t1.cntry,impic.t1.var,const,impic.t1.track,impic.t1.year 1 Using where
因此,我的索引ddef
(cntry
,var
,类型
,轨道
,年份
)正在使用中!成功!(你可以忽略其他指数,我知道并非所有指数都有意义……)
还有一个好处:有没有一种更短的方法来编写ON子句?data\u der=data\u der\u testing?
v1305
是一个文本列,mysql很难使用它,除非使用一些全文索引。另外,我很确定索引合并不能与文本列一起工作,因此引擎必须在索引中进行选择,而不是将它们组合起来。通常,中(…)
的效率特别低。这里很可能就是这种情况,因为它被标记为依赖子查询
。如果可能的话,您(或其他人)必须将其重写为一个JOIN
。第一个问题是SQL优化程序认为它必须对您的数据运行表扫描。可能您的索引没有足够的选择性,所以mysql选择对表数据进行完整的表扫描。这真的应该是一个加入,因为大家都知道这会让事情变得更糟。谢谢你们的评论。根据您的建议,我发布了一个连接作为下面的解决方案。是的,数据测试
=数据测试
,谢谢注意!