我有一个包含各种对象类型的数据库,每个对象类型由两个三字母代码定义,不包括列表包括:
我有一个名为obj_rels的关系表,其中包含以下字段:
关系表目前有大约95,000条记录。
对象类型可以是pri_type或sec_type。例如,事务和文件可能是相关的,因此TRA可能是主要的,而FIL则是次要的。或者文件和注释可能是相关的,因此在这种情况下文件FIL可能是主要的,而COM辅助。
所以我需要一个查询来拉取,例如,与文件相关的所有内容。
我正在做的是:
SELECT pri_type, pri_type_id, sec_type, sec_type_id, effective_on
FROM obj_rels
WHERE ( trashed_on = 0 OR ISNULL(trashed_on) ) AND pri_type = 'FIL' AND pri_type_id = 1234
UNION
SELECT sec_type, sec_type_id, pri_type, pri_type_id, effective_on
FROM obj_rels
WHERE ( trashed_on = 0 OR ISNULL(trashed_on) ) AND sec_type = 'FIL' AND sec_type_id = 1234
对于像这样的一次性选择,它并不太糟糕。但是,当我执行更大的查询时,说我需要所有事务以及与每个单独事务相关的文件数量,这些查询会大大减慢我的Web应用程序的运行速度。我目前正在处理的查询在大约0.4秒内运行而没有文件&注释计数,计数约2.1秒。这是我试图写的查询的简化版本:
SELECT *
FROM tra_transactions AS tra
LEFT JOIN (
SELECT pri_type, pri_type_id, COUNT(sec_type_id) AS cts
FROM (
SELECT pri_type, pri_type_id, sec_type, sec_type_id, effective_on
FROM obj_rels WHERE pri_type = 'TRA' AND sec_type = 'FIL' AND ( trashed_on = 0 OR ISNULL(trashed_on) ) AND effective_on <= NOW()
UNION
SELECT sec_type, sec_type_id, pri_type, pri_type_id, effective_on
FROM obj_rels WHERE sec_type = 'TRA' AND pri_type = 'FIL' AND ( trashed_on = 0 OR ISNULL(trashed_on) ) AND effective_on <= NOW()
) as qry
GROUP BY pri_type, pri_type_id
) AS rel ON rel.pri_type_id = tra.id
WHERE tra.ent_id = 40
是否有更好的方法来构建关系表以获得联盟和我需要运行的子查询?
我想知道每个关系是否更好地存储两个条目,以便每个类型的记录类型为主要和次要而不是一起运行多个查询?这会使表的大小加倍,那么运行连接查询会更有效吗?有更好的架构吗?
提前致谢!
...评论......我被要求提供索引。这是obj_rels表的Create语句......我不太擅长索引,所以我可能做了一些过度杀伤:
CREATE TABLE `obj_rels` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pri_type` varchar(3) DEFAULT NULL,
`pri_type_id` int(11) DEFAULT NULL,
`sec_type` varchar(3) DEFAULT NULL,
`sec_type_id` int(11) DEFAULT NULL,
`effective_on` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`trashed_by` int(11) DEFAULT NULL,
`trashed_on` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `types` (`pri_type`,`sec_type`),
KEY `pri_type` (`pri_type`),
KEY `pri_type_id` (`pri_type_id`),
KEY `sec_type` (`sec_type`),
KEY `sec_type_id` (`sec_type_id`),
KEY `trashed_on` (`trashed_on`),
KEY `pri_type_id_2` (`pri_type_id`,`pri_type`,`trashed_on`),
KEY `sec_type_id_2` (`sec_type_id`,`sec_type`,`trashed_on`)
) ENGINE=InnoDB AUTO_INCREMENT=94530 DEFAULT CHARSET=utf8;