优化使用自连接的MySQL视图
我有一个需要执行自联接的表:优化使用自连接的MySQL视图,mysql,views,self-join,Mysql,Views,Self Join,我有一个需要执行自联接的表: +----+------+-------+-----+------+-------+-----------+---------+------+ | id | type | panel | row | port | cable | cablePort | conType | B_id | +----+------+-------+-----+------+-------+-----------+---------+------+ | 1 | 1 | A
+----+------+-------+-----+------+-------+-----------+---------+------+
| id | type | panel | row | port | cable | cablePort | conType | B_id |
+----+------+-------+-----+------+-------+-----------+---------+------+
| 1 | 1 | A | 1 | 1 | | | 1 | |
| 2 | 1 | A | 1 | 2 | | | 1 | |
| 3 | 1 | A | 1 | 3 | | | 1 | |
| 4 | 1 | A | 1 | 4 | | | 1 | |
| 5 | 1 | A | 1 | 5 | | | 1 | |
| 6 | 1 | A | 1 | 6 | | | 1 | |
| 7 | 1 | A | 1 | 7 | | | 1 | |
| 8 | 1 | A | 1 | 8 | | | 1 | |
| 9 | 1 | A | 1 | 9 | | | 1 | |
| 10 | 1 | A | 1 | 10 | | | 1 | |
+----+------+-------+-----+------+-------+-----------+---------+------+
(需要对id和B_id执行自连接)
希望此表的结果是:
+------+--------+---------+-------+--------+---------+-------------+-----------+--------+--------+---------+-------+--------+---------+-------------+-----------+
| a_id | a_type | a_panel | a_row | a_port | a_cable | a_cablePort | a_conType | b_B_id | b_type | b_panel | b_row | b_port | b_cable | b_cablePort | b_conType |
+------+--------+---------+-------+--------+---------+-------------+-----------+--------+--------+---------+-------+--------+---------+-------------+-----------+
| 1 | 1 | A | 1 | 1 | NULL | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 2 | 1 | A | 1 | 2 | NULL | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 3 | 1 | A | 1 | 3 | NULL | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 4 | 1 | A | 1 | 4 | NULL | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 5 | 1 | A | 1 | 5 | NULL | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 6 | 1 | A | 1 | 6 | NULL | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 7 | 1 | A | 1 | 7 | NULL | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 8 | 1 | A | 1 | 8 | NULL | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 9 | 1 | A | 1 | 9 | NULL | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
| 10 | 1 | A | 1 | 10 | NULL | NULL | 1 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+------+--------+---------+-------+--------+---------+-------------+-----------+--------+--------+---------+-------+--------+---------+-------------+-----------+
(请注意,我没有在此记录中指定任何B_id)
以下是我的表格结构:
╔═══════════════╦═════════════╦══════╦═════╦═════════╦════════════════╗
║ Field ║ Type ║ Null ║ Key ║ Default ║ Extra ║
╠═══════════════╬═════════════╬══════╬═════╬═════════╬════════════════╣
║ id ║ int(11) ║ NO ║ PRI ║ NULL ║ auto_increment ║
║ type ║ varchar(45) ║ YES ║ ║ NULL ║ ║
║ panel ║ varchar(45) ║ YES ║ ║ NULL ║ ║
║ row ║ varchar(45) ║ YES ║ ║ NULL ║ ║
║ port ║ varchar(45) ║ YES ║ ║ NULL ║ ║
║ cable ║ varchar(45) ║ YES ║ ║ NULL ║ ║
║ cablePort ║ varchar(45) ║ YES ║ ║ NULL ║ ║
║ conType ║ varchar(45) ║ YES ║ MUL ║ NULL ║ ║
║ B_id ║ int ║ YES ║ MUL ║ NULL ║ ║
╚═══════════════╩═════════════╩══════╩═════╩═════════╩════════════════╝
最后,我的观点是执行自连接
select distinct
`a`.`id` AS `a_id`,
`a`.`type` AS `a_type`,
`a`.`panel` AS `a_panel`,
`a`.`row` AS `a_row`,
`a`.`port` AS `a_port`,
`a`.`cable` AS `a_cable`,
`a`.`cablePort` AS `a_cablePort`,
`a`.`conType` AS `a_conType`,
`a`.`B_id` AS `b_B_id`,
`b`.`type` AS `b_type`,
`b`.`panel` AS `b_panel`,
`b`.`row` AS `b_row`,
`b`.`port` AS `b_port`,
`b`.`cable` AS `b_cable`,
`b`.`cablePort` AS `b_cablePort`,
`b`.`conType` AS `b_conType`
from `mmr` `a`
left join `mmr` `b`
ON (`a`.`id` = `b`.`B_id`)
问题是,执行我的视图进行数据提取是不可接受的。仅提取10000条记录大约需要1分钟或更长时间
您能告诉我如何优化我的查询以及是什么导致数据提取执行缓慢吗
其他:
我还创建了另一个视图,它将从上面的视图中提取数据。该视图还需要操作数据并提供更详细的数据以供查看
select
`a`.`a_id` AS `a_id`,
`a`.`a_type` AS `a_type`,
`a`.`a_panel` AS `a_panel`,
`a`.`a_row` AS `a_row`,
`a`.`a_port` AS `a_port`,
`a`.`a_cable` AS `a_cable`,
`a`.`a_cablePort` AS `a_cablePort`,
`a`.`a_conType` AS `a_conType`,
`a`.`a_conTypeDesc` AS `a_conTypeDesc`,
`a`.`b_B_id` AS `b_B_id`,
`a`.`b_type` AS `b_type`,
`a`.`b_panel` AS `b_panel`,
`a`.`b_row` AS `b_row`,
`a`.`b_port` AS `b_port`,
`a`.`b_cable` AS `b_cable`,
`a`.`b_cablePort` AS `b_cablePort`,
`a`.`b_conType` AS `b_conType`,
`a`.`b_conTypeDesc` AS `b_conTypeDesc`,
(case
when
((`a`.`b_panel` = `b`.`b_panel`)
and (`a`.`b_row` = `b`.`b_row`))
then
concat(`a`.`b_panel`,
_latin1'-',
`a`.`b_row`,
_latin1'(',
(case
when (cast(`a`.`b_port` as signed) > cast(`b`.`b_port` as signed)) then `b`.`b_port`
else `a`.`b_port`
end),
_latin1',',
(case
when (cast(`a`.`b_port` as signed) < cast(`b`.`b_port` as signed)) then `b`.`b_port`
else `a`.`b_port`
end),
_latin1')')
when
((`a`.`b_row` <> `b`.`b_row`)
and (`a`.`b_cablePort` <> _latin1''))
then
concat(`a`.`b_panel`,
_latin1'-',
`a`.`b_row`,
_latin1'(',
`a`.`b_port`,
_latin1'),',
`b`.`b_row`,
_latin1'(',
`b`.`b_port`,
_latin1')')
else concat(`a`.`b_panel`,
_latin1'-',
`a`.`b_row`,
_latin1'(',
`a`.`b_port`,
_latin1')')
end) AS `mmrport`
from
`vw_details` `a`
left join `vw_details` `b` ON (`a`.`b_cable` = `b`.`b_cable`)
and (`a`.`b_cablePort` = `b`.`b_cablePort`)
and (`a`.`b_B_id` <> `b`.`b_B_id`)
and (`a`.`b_type` = `b`.`b_type`)
and (`a`.`b_panel` = `b`.`b_panel`)
and (`a`.`b_conType` = `b`.`b_conType`)
新:
问题:为什么在MySQL中处理15000条记录的表上的一个简单的自连接需要很长时间?
如果您能就此提出建议,我将不胜感激。尝试在第一步中将连接条件更改为where
select
`a`.`a_id` AS `a_id`,
`a`.`a_type` AS `a_type`,
`a`.`a_panel` AS `a_panel`,
`a`.`a_row` AS `a_row`,
`a`.`a_port` AS `a_port`,
`a`.`a_cable` AS `a_cable`,
`a`.`a_cablePort` AS `a_cablePort`,
`a`.`a_conType` AS `a_conType`,
`a`.`a_conTypeDesc` AS `a_conTypeDesc`,
`a`.`b_B_id` AS `b_B_id`,
`a`.`b_type` AS `b_type`,
`a`.`b_panel` AS `b_panel`,
`a`.`b_row` AS `b_row`,
`a`.`b_port` AS `b_port`,
`a`.`b_cable` AS `b_cable`,
`a`.`b_cablePort` AS `b_cablePort`,
`a`.`b_conType` AS `b_conType`,
`a`.`b_conTypeDesc` AS `b_conTypeDesc`,
(case
when
((`a`.`b_panel` = `b`.`b_panel`)
and (`a`.`b_row` = `b`.`b_row`))
then
concat(`a`.`b_panel`,
_latin1'-',
`a`.`b_row`,
_latin1'(',
(case
when (cast(`a`.`b_port` as signed) > cast(`b`.`b_port` as signed)) then `b`.`b_port`
else `a`.`b_port`
end),
_latin1',',
(case
when (cast(`a`.`b_port` as signed) < cast(`b`.`b_port` as signed)) then `b`.`b_port`
else `a`.`b_port`
end),
_latin1')')
when
((`a`.`b_row` <> `b`.`b_row`)
and (`a`.`b_cablePort` <> _latin1''))
then
concat(`a`.`b_panel`,
_latin1'-',
`a`.`b_row`,
_latin1'(',
`a`.`b_port`,
_latin1'),',
`b`.`b_row`,
_latin1'(',
`b`.`b_port`,
_latin1')')
else concat(`a`.`b_panel`,
_latin1'-',
`a`.`b_row`,
_latin1'(',
`a`.`b_port`,
_latin1')')
end) AS `mmrport`
from
`vw_details` `a`
left join `vw_details` `b` ON (`a`.`b_cable` = `b`.`b_cable`)
WHERE (`a`.`b_cablePort` = `b`.`b_cablePort`)
and (`a`.`b_B_id` <> `b`.`b_B_id`)
and (`a`.`b_type` = `b`.`b_type`)
and (`a`.`b_panel` = `b`.`b_panel`)
and (`a`.`b_conType` = `b`.`b_conType`)
选择
`a`.`a_id`作为'a_id`,
`a`.`a_type`作为`a_type`,
`a`.`a_panel`作为`a_panel`,
`a`.`a_row`作为'a_row`,
`a`.`a_port`作为`a_port`,
`a`.`a_cable`作为'a_cable`,
`a`.`a_cablePort`作为'a_cablePort`,
`a`.`a_conType`作为'a_conType`,
`a`.`a_conTypeDesc`作为`a_conTypeDesc`,
`a`.`b_b_id`作为`b_b_id`,
`a`.`b_type`作为`b_type`,
`a`.`b_panel`作为`b_panel`,
`a`.`b_row`作为`b_row`,
`a`.`b_port`作为`b_port`,
`a`.`b_cable`作为`b_cable`,
`a`.`b_cablePort`作为`b_cablePort`,
`a`.`b_conType`作为`b_conType`,
`a`.`b_conTypeDesc`作为`b_conTypeDesc`,
(案例
什么时候
(`a`.`b_面板`=`b`.`b_面板`)
和(`a`.`b_行`=`b`.`b_行`)
然后
concat(`a`.`b_面板`,
_拉丁文1'-',
`a`.`b_行`,
_拉丁文1'(',
(案例
当(cast(`a`.`b_port`as signed)>cast(`b`.`b_port`as signed))时,则为`b`.`b_port`as signed)`
其他'a`.'b_端口`
(完),,
_拉丁文1',',
(案例
当(cast(`a`.`b_port`as signed)
如果不需要空记录,请使用内部联接而不是左联接。
还有一个建议,如果您使用的是php或asp.net之类的语言,请从查询中删除案例,并使用服务器端语言执行此操作。这将提高性能。使用group by而不是distinct。当记录为空时,为什么还要进行自连接呢?为什么是
a\u id
aINT
和B\u id
aVARCHAR(45)
?。我的意思是从varchar
连接到int
没有意义?这将是一个隐式转换,需要时间尝试解释我们的查询并发布有问题的结果。哦,是的。。。这应该是B_id,也应该是int,将在我的帖子上编辑。@raheelshan假设B_id的详细信息不是null,实际上是id本身的实例。我需要null值。我会试试这个。为什么在MySQL中做一个简单的自连接需要很长时间?我假设你的表中有很多k记录。此外,您可能没有添加索引,因此它会变慢。还有一件事,你有导致延误的案例
select
`a`.`a_id` AS `a_id`,
`a`.`a_type` AS `a_type`,
`a`.`a_panel` AS `a_panel`,
`a`.`a_row` AS `a_row`,
`a`.`a_port` AS `a_port`,
`a`.`a_cable` AS `a_cable`,
`a`.`a_cablePort` AS `a_cablePort`,
`a`.`a_conType` AS `a_conType`,
`a`.`a_conTypeDesc` AS `a_conTypeDesc`,
`a`.`b_B_id` AS `b_B_id`,
`a`.`b_type` AS `b_type`,
`a`.`b_panel` AS `b_panel`,
`a`.`b_row` AS `b_row`,
`a`.`b_port` AS `b_port`,
`a`.`b_cable` AS `b_cable`,
`a`.`b_cablePort` AS `b_cablePort`,
`a`.`b_conType` AS `b_conType`,
`a`.`b_conTypeDesc` AS `b_conTypeDesc`,
(case
when
((`a`.`b_panel` = `b`.`b_panel`)
and (`a`.`b_row` = `b`.`b_row`))
then
concat(`a`.`b_panel`,
_latin1'-',
`a`.`b_row`,
_latin1'(',
(case
when (cast(`a`.`b_port` as signed) > cast(`b`.`b_port` as signed)) then `b`.`b_port`
else `a`.`b_port`
end),
_latin1',',
(case
when (cast(`a`.`b_port` as signed) < cast(`b`.`b_port` as signed)) then `b`.`b_port`
else `a`.`b_port`
end),
_latin1')')
when
((`a`.`b_row` <> `b`.`b_row`)
and (`a`.`b_cablePort` <> _latin1''))
then
concat(`a`.`b_panel`,
_latin1'-',
`a`.`b_row`,
_latin1'(',
`a`.`b_port`,
_latin1'),',
`b`.`b_row`,
_latin1'(',
`b`.`b_port`,
_latin1')')
else concat(`a`.`b_panel`,
_latin1'-',
`a`.`b_row`,
_latin1'(',
`a`.`b_port`,
_latin1')')
end) AS `mmrport`
from
`vw_details` `a`
left join `vw_details` `b` ON (`a`.`b_cable` = `b`.`b_cable`)
WHERE (`a`.`b_cablePort` = `b`.`b_cablePort`)
and (`a`.`b_B_id` <> `b`.`b_B_id`)
and (`a`.`b_type` = `b`.`b_type`)
and (`a`.`b_panel` = `b`.`b_panel`)
and (`a`.`b_conType` = `b`.`b_conType`)