mysql - 为什么这些 mysql 查询在本地和舞台上运行不同?
问题描述
我们有一个查询,当在本地运行时会快速返回,但是当在我们的登台环境中运行相同的查询时,它需要很长时间。
本地数据库是阶段数据库的副本(截至上次备份),因此两者应该非常相似。当我运行这个解释命令时,我得到了非常不同的结果。
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
我在解释命令中注意到的差异是: * 在本地看到“分区”和“过滤”列,但在舞台上看不到 * 在本地看到 PRIMARY 的“类型”值说“索引”,在舞台上说“全部”
有谁知道为什么两种环境中的结果如此不同?
解决方案
如果表定义相同,包括具有相同顺序的列的相同索引,那么我会在 5.7 中将差异放在优化器中的差异/改进上。
看起来像 5.7,Oracle 选择使用覆盖索引。在 5.6 中,它正在访问实际的表。
我会避免IN (subquery)
构造,而是使用反连接模式。这将给出与原始结果大致相同的结果;如果子查询返回 NULL 值,那么原始的最大区别将不会返回任何行。
EXPLAIN
SELECT a.cs_uid
FROM mydb.article a
LEFT
JOIN mydb.article_wordcount c
ON c.articleid = a.cs_uid
WHERE c.articleid IS NULL
NOT EXISTS 的等效结果;解释输出将非常相似
EXPLAIN
SELECT a.cs_uid
FROM mydb.article a
WHERE NOT EXISTS
( SELECT 1
FROM mydb.article_wordcount c
WHERE c.articleid = a.cs_uid
)
推荐阅读
- ssl - 无法为 SSL/TLS 安全通道 .net 核心建立信任关系
- javascript - Javascript DOM 元素
- arrays - 如何为 SwiftUI 新闻应用设置模型
- ios - ios sqlite 错误:尝试写入只读数据库
- android - 将 NavigationView 与 SlidingPaneLayout 一起使用
- excel - MSCOMCT2.OCX 注册成功但未在附加控件中列出
- python - 如何将绘图中的图片用于进一步的代码
- html - 在 Visual Code HTML 中输入 b4 时如何包含 font-awesome?
- java - 等效于 java KeyPairGenerator 的 Openssl 库
- tomcat - 将 Tomcat 9 重定向到 FQDN