优化使用自连接的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
a
INT
B\u id
a
VARCHAR(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`)