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 = []) {
// Replace tabs with spaces for debugging purposes
$sql = str_replace("\t", " ", $sql);
if($this->settings->get("env.mode") == "development")
error_log("[Database/SQL] $sql");
// FUTURE: Optionally cache prepared statements?
// Note that we replace tabs with spaces for debugging purposes
$statement = $this->connection->prepare(str_replace("\t", " ", $sql));
$statement = $this->connection->prepare($sql);
$statement->execute($variables);
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_storedon = "storedon";
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_lat = "reading_latitude";
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_metadata")}.{$s("column_metadata_device_id")},
COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
) AS datetime,
{$s("table_name_metadata")}.{$s("column_metadata_datetime")} AS datetime,
COUNT({$s("table_name_metadata")}.{$s("column_metadata_device_id")}) AS record_count
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
WHERE
COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$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
{$s("table_name_metadata")}.{$s("column_metadata_datetime")} >= :start_datetime AND
{$s("table_name_metadata")}.{$s("column_metadata_datetime")} <= :end_datetime
AND
{$s("table_name_values")}.{$s("column_values_reading_type")} = :reading_type
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,
// The database likes strings, not PHP DateTime() instances
@ -111,14 +107,8 @@ class MariaDBMeasurementDataRepository implements IMeasurementDataRepository {
$s = $this->get_static;
return $this->database->query(
"SELECT
MIN(COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$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
MIN({$s("table_name_metadata")}.{$s("column_metadata_datetime")}) AS start,
MAX({$s("table_name_metadata")}.{$s("column_metadata_datetime")}) AS end
FROM {$s("table_name_metadata")}
WHERE {$s("table_name_metadata")}.{$s("column_metadata_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")},
MIN({$s("table_name_values")}.{$s("column_values_reading_id")}) AS {$s("column_values_reading_id")},
MIN(COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
)) AS datetime
MIN({$s("table_name_metadata")}.{$s("column_metadata_datetime")}) AS datetime
FROM {$s("table_name_values")}
JOIN {$s("table_name_metadata")} ON
{$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_values")}.{$s("column_values_reading_type")} = :reading_type AND
COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$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
GROUP BY CEIL(UNIX_TIMESTAMP(COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
)) / :average_seconds);", [
{$s("table_name_metadata")}.{$s("column_metadata_datetime")} >= :start_datetime AND
{$s("table_name_metadata")}.{$s("column_metadata_datetime")} <= :end_datetime
GROUP BY CEIL(UNIX_TIMESTAMP({$s("table_name_metadata")}.{$s("column_metadata_datetime")}) / :average_seconds);", [
"device_id" => $device_id,
"reading_type" => $type_id,
"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_reading_id")} AS {$s("column_values_reading_id")},
COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
) AS datetime
{$s("table_name_metadata")}.{$s("column_metadata_datetime")} AS datetime
FROM {$s("table_name_values")}
JOIN {$s("table_name_metadata")} ON
{$s("table_name_metadata")}.{$s("column_metadata_id")} = {$s("table_name_values")}.{$s("column_values_reading_id")}
WHERE
{$s("table_name_metadata")}.{$s("column_metadata_device_id")} = :device_id AND
{$s("table_name_values")}.{$s("column_values_reading_type")} = :reading_type
ORDER BY COALESCE(
{$s("table_name_metadata")}.{$s("column_metadata_recordedon")},
{$s("table_name_metadata")}.{$s("column_metadata_storedon")}
) DESC
ORDER BY {$s("table_name_metadata")}.{$s("column_metadata_datetime")} DESC
LIMIT :count;", [
"device_id" => $device_id,
"reading_type" => $type_id,