MySQL计算字段在SELECT子句中重用

时间:2015-01-19 10:45:42

标签: mysql calculated-columns calculated-field

您将如何完成此任务以获得最佳性能?

表架构:

CREATE TABLE `test_truck_report` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `truck_id` INT(11) NOT NULL,
    `odometer_initial` INT(11) NOT NULL,
    `odometer_final` INT(11) NOT NULL,
    `fuel_initial` INT(11) NOT NULL,
    `fuel_final` INT(11) NOT NULL,
    PRIMARY KEY (`id`)
)
ENGINE=InnoDB;

我试图执行的是这个查询:

SELECT
    truck_id,
    (odometer_final - odometer_initial) AS mileage,
    (fuel_initial - fuel_final) AS consumed_fuel,
    (consumed_fuel / mileage) AS consumption_per_km
FROM
    test_truck_report
WHERE
    consumption_per_km > 2

不知何故,这在第一眼看上去是显而易见的,但是我不得不使用这个查询:

SELECT
    truck_id,
    (odometer_final - odometer_initial) AS mileage,
    (fuel_initial - fuel_final) AS consumed_fuel,
    ((fuel_initial - fuel_final) / (odometer_final - odometer_initial)) AS consumption_per_km
FROM
    test_truck_report
WHERE
    ((fuel_initial - fuel_final) / (odometer_final - odometer_initial)) > 2

我假设每次需要放置每个计算字段时不断重新计算会显着降低性能。这只是一个测试用例,实际工作表有50多个字段,一些计算字段包含10个以上的操作数。因此,目前这是一个非常巨大的问题。

为什么我不想实际创建这些字段并执行以下操作:

UPDATE 
    `test_truck_report` 
SET
    consumed_fuel = fuel_initial - fuel_final

是用户不断更新现有记录,在这种情况下,我需要不断更新该数据。 那么你认为创建实际领域更好吗?或者有更好的方法吗?

感谢。

1 个答案:

答案 0 :(得分:1)

尝试使用观点:

我们需要一个辅助视图:

CREATE OR REPLACE VIEW vw_truck_data AS
SELECT truck_id,
      (odometer_final - odometer_initial) AS mileage,
      (fuel_initial - fuel_final)         AS consumed_fuel
FROM test_truck_report;

最后的观点:

CREATE OR REPLACE VIEW vw_truck_consumption AS
SELECT data.*,
      (data.consumed_fuel / data.mileage) AS consumption_per_km
FROM vw_truck_data data;

现在,您可以随时随地查询:

SELECT *
  FROM vw_truck_consumption 
 WHERE consumption_per_km > 2

这样MySQL应该只能减去每个字段一次,因此性能应该至少与您的解决方案一样好或更好。通常,添加字段的CPU成本小于从数据库中检索数据的成本,但当然这取决于您的硬件,mysql版本,配置和数据分布。如果确实存在问题,请做一些测量。

无论如何,请记住您正在使用consumption_per_km进行查询过滤,这是一个字段功能。由于MySQL似乎lack funtional indexes,它肯定会扫描整个表并且速度很慢。