Optimise some queries using the new datetime computed column, but there's more work to do.

The fetch-data query in particular is using the wrong index.
This commit is contained in:
Starbeamrainbowlabs 2019-06-22 11:50:23 +01:00
parent 3bb73ccb12
commit b4ae0b457b
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
2 changed files with 21 additions and 47 deletions

View file

@ -53,12 +53,14 @@ class Database
} }
public function query($sql, $variables = []) { public function query($sql, $variables = []) {
// Replace tabs with spaces for debugging purposes
$sql = str_replace("\t", " ", $sql);
if($this->settings->get("env.mode") == "development") if($this->settings->get("env.mode") == "development")
error_log("[Database/SQL] $sql"); error_log("[Database/SQL] $sql");
// FUTURE: Optionally cache prepared statements? // FUTURE: Optionally cache prepared statements?
// Note that we replace tabs with spaces for debugging purposes $statement = $this->connection->prepare($sql);
$statement = $this->connection->prepare(str_replace("\t", " ", $sql));
$statement->execute($variables); $statement->execute($variables);
return $statement; // fetchColumn(), fetchAll(), etc. are defined on the statement, not the return value of execute() return $statement; // fetchColumn(), fetchAll(), etc. are defined on the statement, not the return value of execute()
} }

View file

@ -20,6 +20,11 @@ class MariaDBMeasurementDataRepository implements IMeasurementDataRepository {
public static $column_metadata_id = "id"; public static $column_metadata_id = "id";
public static $column_metadata_storedon = "storedon"; public static $column_metadata_storedon = "storedon";
public static $column_metadata_recordedon = "recordedon"; public static $column_metadata_recordedon = "recordedon";
/**
* A coaleasce of storedon and recorded on.
* @var string
*/
public static $column_metadata_datetime = "datetime";
public static $column_metadata_device_id = "device_id"; public static $column_metadata_device_id = "device_id";
public static $column_metadata_lat = "reading_latitude"; public static $column_metadata_lat = "reading_latitude";
public static $column_metadata_long = "reading_longitude"; public static $column_metadata_long = "reading_longitude";
@ -78,26 +83,17 @@ class MariaDBMeasurementDataRepository implements IMeasurementDataRepository {
{$s("table_name_values")}.{$s("column_values_reading_id")}, {$s("table_name_values")}.{$s("column_values_reading_id")},
{$s("table_name_metadata")}.{$s("column_metadata_device_id")}, {$s("table_name_metadata")}.{$s("column_metadata_device_id")},
COALESCE( {$s("table_name_metadata")}.{$s("column_metadata_datetime")} AS datetime,
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
) AS datetime,
COUNT({$s("table_name_metadata")}.{$s("column_metadata_device_id")}) AS record_count COUNT({$s("table_name_metadata")}.{$s("column_metadata_device_id")}) AS record_count
FROM {$s("table_name_values")} FROM {$s("table_name_values")}
JOIN {$s("table_name_metadata")} ON {$s("table_name_values")}.{$s("column_values_reading_id")} = {$s("table_name_metadata")}.id JOIN {$s("table_name_metadata")} ON {$s("table_name_values")}.{$s("column_values_reading_id")} = {$s("table_name_metadata")}.id
WHERE WHERE
COALESCE( {$s("table_name_metadata")}.{$s("column_metadata_datetime")} >= :start_datetime AND
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")}, {$s("table_name_metadata")}.{$s("column_metadata_datetime")} <= :end_datetime
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
) >= :start_datetime AND
COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
) <= :end_datetime
AND AND
{$s("table_name_values")}.{$s("column_values_reading_type")} = :reading_type {$s("table_name_values")}.{$s("column_values_reading_type")} = :reading_type
GROUP BY {$s("table_name_metadata")}.{$s("column_metadata_device_id")} GROUP BY {$s("table_name_metadata")}.{$s("column_metadata_device_id")}
ORDER BY {$s("table_name_metadata")}.{$s("column_metadata_recordedon")} ORDER BY {$s("table_name_metadata")}.{$s("column_metadata_datetime")}
", [ ", [
"reading_type" => $type_id, "reading_type" => $type_id,
// The database likes strings, not PHP DateTime() instances // The database likes strings, not PHP DateTime() instances
@ -111,14 +107,8 @@ class MariaDBMeasurementDataRepository implements IMeasurementDataRepository {
$s = $this->get_static; $s = $this->get_static;
return $this->database->query( return $this->database->query(
"SELECT "SELECT
MIN(COALESCE( MIN({$s("table_name_metadata")}.{$s("column_metadata_datetime")}) AS start,
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")}, MAX({$s("table_name_metadata")}.{$s("column_metadata_datetime")}) AS end
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
)) AS start,
MAX(COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
)) AS end
FROM {$s("table_name_metadata")} FROM {$s("table_name_metadata")}
WHERE {$s("table_name_metadata")}.{$s("column_metadata_device_id")} = :device_id;", [ WHERE {$s("table_name_metadata")}.{$s("column_metadata_device_id")} = :device_id;", [
"device_id" => $device_id "device_id" => $device_id
@ -135,10 +125,7 @@ class MariaDBMeasurementDataRepository implements IMeasurementDataRepository {
AVG({$s("table_name_values")}.{$s("column_values_value")}) AS {$s("column_values_value")}, AVG({$s("table_name_values")}.{$s("column_values_value")}) AS {$s("column_values_value")},
MIN({$s("table_name_values")}.{$s("column_values_reading_id")}) AS {$s("column_values_reading_id")}, MIN({$s("table_name_values")}.{$s("column_values_reading_id")}) AS {$s("column_values_reading_id")},
MIN(COALESCE( MIN({$s("table_name_metadata")}.{$s("column_metadata_datetime")}) AS datetime
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
)) AS datetime
FROM {$s("table_name_values")} FROM {$s("table_name_values")}
JOIN {$s("table_name_metadata")} ON JOIN {$s("table_name_metadata")} ON
{$s("table_name_metadata")}.{$s("column_metadata_id")} = {$s("table_name_values")}.{$s("column_values_reading_id")} {$s("table_name_metadata")}.{$s("column_metadata_id")} = {$s("table_name_values")}.{$s("column_values_reading_id")}
@ -146,18 +133,9 @@ class MariaDBMeasurementDataRepository implements IMeasurementDataRepository {
{$s("table_name_metadata")}.{$s("column_metadata_device_id")} = :device_id AND {$s("table_name_metadata")}.{$s("column_metadata_device_id")} = :device_id AND
{$s("table_name_values")}.{$s("column_values_reading_type")} = :reading_type AND {$s("table_name_values")}.{$s("column_values_reading_type")} = :reading_type AND
COALESCE( {$s("table_name_metadata")}.{$s("column_metadata_datetime")} >= :start_datetime AND
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")}, {$s("table_name_metadata")}.{$s("column_metadata_datetime")} <= :end_datetime
{$s("table_name_metadata")}.{$s("column_metadata_storedon")} GROUP BY CEIL(UNIX_TIMESTAMP({$s("table_name_metadata")}.{$s("column_metadata_datetime")}) / :average_seconds);", [
) >= :start_datetime AND
COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
) <= :end_datetime
GROUP BY CEIL(UNIX_TIMESTAMP(COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
)) / :average_seconds);", [
"device_id" => $device_id, "device_id" => $device_id,
"reading_type" => $type_id, "reading_type" => $type_id,
"start_datetime" => $start->format(\DateTime::ISO8601), "start_datetime" => $start->format(\DateTime::ISO8601),
@ -176,20 +154,14 @@ class MariaDBMeasurementDataRepository implements IMeasurementDataRepository {
{$s("table_name_values")}.{$s("column_values_value")} AS {$s("column_values_value")}, {$s("table_name_values")}.{$s("column_values_value")} AS {$s("column_values_value")},
{$s("table_name_values")}.{$s("column_values_reading_id")} AS {$s("column_values_reading_id")}, {$s("table_name_values")}.{$s("column_values_reading_id")} AS {$s("column_values_reading_id")},
COALESCE( {$s("table_name_metadata")}.{$s("column_metadata_datetime")} AS datetime
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
) AS datetime
FROM {$s("table_name_values")} FROM {$s("table_name_values")}
JOIN {$s("table_name_metadata")} ON JOIN {$s("table_name_metadata")} ON
{$s("table_name_metadata")}.{$s("column_metadata_id")} = {$s("table_name_values")}.{$s("column_values_reading_id")} {$s("table_name_metadata")}.{$s("column_metadata_id")} = {$s("table_name_values")}.{$s("column_values_reading_id")}
WHERE WHERE
{$s("table_name_metadata")}.{$s("column_metadata_device_id")} = :device_id AND {$s("table_name_metadata")}.{$s("column_metadata_device_id")} = :device_id AND
{$s("table_name_values")}.{$s("column_values_reading_type")} = :reading_type {$s("table_name_values")}.{$s("column_values_reading_type")} = :reading_type
ORDER BY COALESCE( ORDER BY {$s("table_name_metadata")}.{$s("column_metadata_datetime")} DESC
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
) DESC
LIMIT :count;", [ LIMIT :count;", [
"device_id" => $device_id, "device_id" => $device_id,
"reading_type" => $type_id, "reading_type" => $type_id,