我们有一个查询,当在本地运行时返回很快,但是当在我们的暂存环境中运行同一个查询时,需要很长时间。
本地数据库是stage数据库的一个副本(从上次备份开始),所以这两个数据库应该非常相似。当我运行这个explain命令时,会得到非常不同的结果。
EXPLAIN SELECT
cs_uid
FROM mydb.article
WHERE cs_uid NOT IN (
SELECT
articleId
FROM mydb.article_wordcount
);
地方的
id |select_type |table |partitions |type |possible_keys |key |key_len |ref |rows |filtered |Extra |
---|------------|---------------------|-----------|------|--------------|----------------|--------|----|-------|---------|-------------------------|
1 |PRIMARY |article | |index | |cs_importFileId |5 | |179869 |100 |Using where; Using index |
2 |SUBQUERY |article_wordcount | |index |awc_articleId |awc_articleId |4 | |294816 |100 |Using index |
STAGE
id |select_type |table |type |possible_keys |key |key_len |ref |rows |Extra |
---|------------|---------------------|------|--------------|--------------|--------|----|-------|------------|
1 |PRIMARY |article |ALL | | | | |269910 |Using where |
2 |SUBQUERY |article_wordcount |index |awc_articleId |awc_articleId |4 | |295417 |Using index |
mysql的版本相似,但并不完全相同:
本地:5.7.24阶段:5.6.38
我在explain命令中注意到的区别是:在本地看到“partitions”和“filtered”列,但在stage上看不到,在local上primary的“type”值表示“index”,在stage上表示“all”
有人知道为什么两种环境下的结果如此不同吗?
2条答案
按热度按时间wbgh16ku1#
如果表定义是相同的,包括具有相同顺序的列的相同索引,那么我将在5.7中的优化器中将差异放在differences/improvements上。
看起来在5.7版本中,oracle选择使用覆盖索引。在5.6中,它访问的是实际的表。
我会避开
IN (subquery)
构造,而不是使用反连接模式。这将给出一个与原始结果基本相等的结果;如果子查询返回空值,则与原始查询的最大区别是不会返回任何行。等价结果不存在;解释输出将非常相似
blpfk2vs2#
这种差异很可能是因为table的大小。而且,索引的基数可能不同。这两者都会影响数据库选择查询计划的方式。