MySql 自连接优化查询

标签 mysql join

我试图从我的数据库中找出一些垃圾数据,其中删除了父项但未删除子项(仅一级)。为了解释这种情况,我提供了一些示例数据。

创建示例表的查询

CREATE TABLE  `parentchild` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parentid` int(10) unsigned DEFAULT NULL,
  `Name` varchar(45) NOT NULL,
  `IsDeleted` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `FK_parentchild_Self` (`parentid`) USING BTREE,
  CONSTRAINT `FK_parentchild_Self` FOREIGN KEY (`parentid`) REFERENCES `parentchild` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1;

插入一些虚拟数据后,表格看起来像

id  parentid    Name     IsDeleted
1               Fruits       1
2     1         Mango        0
3     1         Apple        0
4               Car          0
5     4         Baleno       0
6     4         Santro       0
7               Animals      0
8     7         Dog          0
9     7         Cat          0

现在我为找出第一级 child 而形成的查询是

SELECT t2.Name AS Name, t1.Name AS ParentName FROM parentchild t1
INNER JOIN parentchild t2 ON t1.ID=t2.ParentID
WHERE t1.IsDeleted=1 AND t2.IsDeleted=0;

我从这个查询中得到的输出似乎没问题

Name    ParentName
Mango   Fruits
Apple   Fruits

但我担心的是性能,因为它的解释输出并不令人满意。

id  select_type table   partitions  type    possible_keys           key                 key_len     ref                 rows    filtered    Extra
1   SIMPLE        t1                ALL     PRIMARY                                                                      8       12.50      Using where
1   SIMPLE        t2                ref     FK_parentchild_Self     FK_parentchild_Self     5       test1.t1.id 2        2       12.50      Using where

任何人都可以让我知道正确的索引或更好的查询来优化这个吗?

我尝试在 Index(id,IsDeleted)Index(parentid,IsDeleted)Index(id, parentid, IsDeleted) 上添加索引 但都无法优化扫描。

在我的暂存环境中,此数据大约为 1 lac 行,它正在扫描所有行以找出 18 条记录,其父项已被删除但它们未被删除。 Here是我的暂存环境的解释。在我的生产环境中有数百万行,所以我无法对大量数据运行此查询。

最佳答案

一个索引策略会使用这个索引:

CREATE INDEX idx2 ON parentchild (ParentID, IsDeleted, Name);

这将加快对 parentchild 的查找,在连接过程中从左到右。另一种可能的策略是:

CREATE INDEX idx1 ON parentchild (ID, IsDeleted, Name);

如果 MySQL 决定这样做,这可能会加速另一个方向的连接。

关于MySql 自连接优化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56701885/

相关文章:

php - Mysql插入不加入的地方

mysql - 如何使用 Laravel 查询生成器计算两种不同格式之间的小时数?

mysql - Sphinx 获得数百万结果

mysql - SQL查询: How to Find the Maxima of Certain Columns within Different Sets of Similar Records?

MySQL 使用 group by 对第二个表进行计数和求和

mysql - 如何计算 Talend on Oracle 中连接的行数

php - COUNT() 正在选择表中的行数

php - 变量变量不起作用

MySQL删除并加入

MySQL 在连接表上返回 Null = 0,并在一个表上进行过滤