可悲的是,我找不到有关我正在尝试做什么的更多信息。我会尝试尽可能简短地分解它。
我正在使用遗留数据库,相信我,它也让我感到沮丧,但它就是这样,所以我们必须在这个参数范围内工作。
我有一个包含数十万行的数据库,还有一个特别需要生成的ornery统计/报告。最初它只是在一个大的查询中,但这使得它真的很令人沮丧,因为它不允许非常干的架构。我将查询分解为几个视图并将它们连接在一起(最终在最终视图中),这对于测试/开发来说很好,但是我确信一些读过这个的更高级/经验的人可能已经猜到了,很慢。加速它的最明显的方法是将“where”子句应用于连接在一起的内部视图。这大大加快了整个事情的发展。
所以,考虑到这一点,我想到了自己
为什么我不能只创建一个模型并定义它应该使用的大讨厌的union / select infested SQL,并将模型的where子句应用于每个子选择。
我的想法是,这基本上会创建一个“虚拟”模型(我无法通过这个名字找到任何东西,所以我在这里抓住),这些模型在任何地方都不存在,但是当“查询”时它会返回瞬态具有关系的对象(最有可能是其他更持久的模型)。
为了说明,我将发布big-nasty-sql。从角度来看,它基本上是总结/统计联盟销售等的统计数据。
SELECT
`traffic`.`date` AS `date`,
`traffic`.`site_id` AS `site_id`,
`traffic`.`partner_id` AS `partner_id`,
`traffic`.`visits` AS `visits`,
`traffic`.`clicks` AS `clicks`,
`traffic`.`signups` AS `signups`,
`payout`.`signup_total` AS `signup_total`,
`payout`.`upgrade_total` AS `upgrade_total`,
`payout`.`recurring_total` AS `recurring_total`,
`payout`.`referring_total` AS `referring_total`,
`payout`.`negative_total` AS `negative_total`,
`payout`.`fee_total` AS `fee_total`,
`payout`.`carryover_total` AS `carryover_total`,
`payout`.`adjustment_total` AS `adjustment_total`,
`payout`.`payment_total` AS `payment_total`,
`payout`.`payment_nums` AS `payment_nums`
FROM (
((SELECT CAST(`traffic_date` AS DATE) AS `date`,
`site_id`,
`partner_id`,
Sum(IF(tracking_type = 1, count, 0)) AS `visits`,
Sum(IF(tracking_type = 6, count, 0)) AS clicks,
Sum(0) AS signups
FROM `tracking`.`tracking_partner_ad_event`
WHERE `partner_id` = 1796279
GROUP BY 1, 2, 3)
UNION
(SELECT CAST(`traffic_date` AS DATE) AS `date`,
`site_id`,
`partner_id`,
Sum(count) AS visits,
Sum(0) AS clicks,
Sum(0) AS signups
FROM `tracking`.`tracking_partner_traffic_visit`
WHERE `partner_id` = 1796279
GROUP BY 1, 2, 3)
UNION
(SELECT CAST(`processed_date` AS DATE) as `date`,
`site_id`,
`partner_id`,
Sum(0) AS visits,
Sum(0) AS clicks,
Sum(1) AS signups
FROM `user_account_entry`
WHERE `trans_type` = 2 AND `status` <> 2 AND `partner_id` = 1796279
GROUP BY 1, 2, 3)
) AS `traffic`
JOIN
(SELECT
`period` AS `period_id`,
`partner_id`,
`processed_date`,
`site_id`,
SUM(IF(`payout_type`=1, amount, 0)) AS `signup_total`,
SUM(IF(`payout_type`=2, amount, 0)) AS `upgrade_total`,
SUM(IF(`payout_type`=3, amount, 0)) AS `recurring_total`,
SUM(IF(`payout_type`=8, amount, 0)) AS `referring_total`,
SUM(IF(`payout_type`=4, amount, 0)) AS `negative_total`,
SUM(IF(`payout_type`=7, amount, 0)) AS `fee_total`,
SUM(IF(`payout_type`=9, amount, 0)) AS `carryover_total`,
SUM(IF(`payout_type`=5, amount, 0)) AS `adjustment_total`,
SUM(IF(`payout_type`=6, amount, 0)) AS `payment_total`,
GROUP_CONCAT(`payment_num` ORDER BY 1) AS `payment_nums`
FROM `partner_account_entry` AS `e`
WHERE `partner_id` = 1796279
GROUP BY 1,2 ORDER BY 1,2
) AS `payout` ON (
(
(`traffic`.`date` = `payout`.`processed_date`) AND
(`traffic`.`site_id` = `payout`.`site_id`) AND
(`traffic`.`partner_id` = `payout`.`partner_id`)
)
)
) GROUP BY 1,2,3 ORDER BY 1
如您所见,通过选择partner_id
,此查询得到了显着优化。
TL; DR:我喜欢将SQL包装在模型中,即使任何查询要求提供partner_id
,也要模拟可以传递并进一步链接的rails AR Object用。
这是不合理的要求吗?一项艰巨的努力?怎么可以这样做?我找不到令我担心的现有例子,但也让我感到困惑;这不是一个合理的策略,为什么不存在解决方案?