我有三个表,bug
,bugrule
和bugtrace
,它们之间的关系是:
bug 1--------N bugrule
id = bugid
bugrule 0---------N bugtrace
id = ruleid
因为我几乎一直对bug <---> bugtrace
之间的关系感兴趣,所以我创建了一个适当的VIEW
,将其用作几个查询的一部分。有趣的是,使用此VIEW
的查询的性能明显比使用基础JOIN
的等效查询差。]
VIEW
定义:
CREATE VIEW bugtracev AS SELECT t.*, r.bugid FROM bugtrace AS t LEFT JOIN bugrule AS r ON t.ruleid=r.id WHERE r.version IS NULL
使用
VIEW
的查询的执行计划(性能不佳:]
mysql> explain SELECT c.id,state, (SELECT COUNT(DISTINCT(t.id)) FROM bugtracev AS t WHERE t.bugid=c.id) FROM bug AS c WHERE c.version IS NULL AND c.id<10; +----+--------------------+-------+-------+---------------+--------+---------+-----------------+---------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+-------+-------+---------------+--------+---------+-----------------+---------+-----------------------+ | 1 | PRIMARY | c | range | id_2,id | id_2 | 8 | NULL | 3 | Using index condition | | 2 | DEPENDENT SUBQUERY | t | index | NULL | ruleid | 9 | NULL | 1426004 | Using index | | 2 | DEPENDENT SUBQUERY | r | ref | id_2,id | id_2 | 8 | bugapp.t.ruleid | 1 | Using where | +----+--------------------+-------+-------+---------------+--------+---------+-----------------+---------+-----------------------+ 3 rows in set (0.00 sec)
直接使用基础
JOIN
执行查询的计划(性能良好):
mysql> explain SELECT c.id,state, (SELECT COUNT(DISTINCT(t.id)) FROM bugtrace AS t LEFT JOIN bugrule AS r ON t.ruleid=r.id WHERE r.version IS NULL AND r.bugid=c.id) FROM bug AS c WHERE c.version IS NULL AND c.id<10; +----+--------------------+-------+-------+---------------+--------+---------+-------------+--------+-----------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+-------+-------+---------------+--------+---------+-------------+--------+-----------------------+ | 1 | PRIMARY | c | range | id_2,id | id_2 | 8 | NULL | 3 | Using index condition | | 2 | DEPENDENT SUBQUERY | r | ref | id_2,id,bugid | bugid | 8 | bugapp.c.id | 1 | Using where | | 2 | DEPENDENT SUBQUERY | t | ref | ruleid | ruleid | 9 | bugapp.r.id | 713002 | Using index | +----+--------------------+-------+-------+---------------+--------+---------+-------------+--------+-----------------------+ 3 rows in set (0.00 sec)
[
CREATE TABLE
语句(由不相关的列减少)是:
mysql> show create table bug;
CREATE TABLE `bug` (
`id` bigint(20) NOT NULL,
`version` int(11) DEFAULT NULL,
`state` varchar(16) DEFAULT NULL,
UNIQUE KEY `id_2` (`id`,`version`),
KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
mysql> show create table bugrule;
CREATE TABLE `bugrule` (
`id` bigint(20) NOT NULL,
`version` int(11) DEFAULT NULL,
`bugid` bigint(20) NOT NULL,
UNIQUE KEY `id_2` (`id`,`version`),
KEY `id` (`id`),
KEY `bugid` (`bugid`),
CONSTRAINT `bugrule_ibfk_1` FOREIGN KEY (`bugid`) REFERENCES `bug` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
mysql> show create table bugtrace;
CREATE TABLE `bugtrace` (
`id` bigint(20) NOT NULL,
`ruleid` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `ruleid` (`ruleid`),
CONSTRAINT `bugtrace_ibfk_1` FOREIGN KEY (`ruleid`) REFERENCES `bugrule` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
我有三个表,bug,bugrule和bugtrace,它们之间的关系是:bug 1 -------- N bugrule id = bugid bugrule 0 --------- N bugtrace id = ruleid因为我快要走了...