以下查询:
select t.code, t.value, t.date
from readings t inner join (
select code, min(date) as MinDate
from readings
where date >= "2018-11-1"
group by code
) tm on t.code = tm.code and t.date = tm.MinDate
需要+1分钟才能回复。
子查询:
select code, min(date) as MinDate
from readings
where date >= "2018-11-1"
group by code
在一秒钟内返回。另外,如果您要处理整个查询并将min()替换为max(),则也只需一秒钟。
我正在使用HeidiSQL,奇怪的是它报告: 1,578秒(+ 61,172秒网络)。但这是没有意义的,因为max()版本返回的数据量与数据大致相同,并且只需一秒钟。
当前索引:
PRIMARY BTREE Yes No id 31096905 A YES
code_date_unique BTREE Yes No code 0 A YES
date 0 A YES
code BTREE No No code 15801 A YES
date BTREE No No date 1943556 A YES
创建表:
CREATE TABLE `readings` (
`id` INT(15) NOT NULL AUTO_INCREMENT,
....
`code` VARCHAR(50) NULL DEFAULT NULL COLLATE 'latin1_spanish_ci',
`value` FLOAT(10,2) NULL DEFAULT NULL,
`date` DATETIME NULL DEFAULT NULL,
....
PRIMARY KEY (`id`),
UNIQUE INDEX `code_date_unique` (`code`, `date`),
INDEX `code` (`code`),
INDEX `code_DateSaved` (`code`, `dateSaved`),
INDEX `date` (`date`),
INDEX `datesaved` (`dateSaved`),
INDEX `origen` (`origen`)
)
COLLATE='utf8_spanish_ci'
ENGINE=MyISAM
AUTO_INCREMENT=584809517
说明:
explain select t.code, t.value, t.date
from readings t
inner join (
select code, min(date) as MinDate
from readings
where date >= "2018-11-1"
group by code
) tm on t.code = tm.code and t.date = tm.MinDate
+------+---------------+--------------+---------+---------------------------------------------+--------------------+-----------+--------------+---------+-----------------------------------------+
| "id" | "select_type" | "table" | "type" | "possible_keys" | "key" | "key_len" | "ref" | "rows" | "Extra" |
| "1" | "PRIMARY" | "<derived2>" | "ALL" | \N | \N | \N | \N | "15052" | "" |
| "1" | "PRIMARY" | "t" | "ref" | "code_date_unique,code,code_DateSaved,date" | "date" | "9" | "tm.MinDate" | "16" | "Using where" |
| "2" | "DERIVED" | "readings" | "range" | "date" | "code_date_unique" | "62" | \N | "10" | "Using where; Using index for group-by" |
答案 0 :(得分:1)
我不知道如何通过重组来加快查询速度。但是我们可以尝试将以下索引添加到<?php
require_once('classes/Database.php');
$db = new Database;
$query = $db->query("SELECT * FROM producten");
$count = $query->rowCount();
if($count > 0) {
while($row = $query->fetch())
{
echo "<tr>";
echo "<td id='td1'>" . $row[0] . "</td>";
echo "<td id='td2'>" . $row[1] . "</td>";
echo "<td id='td3'>" . $row[2] . "</td>";
echo "<td id='td4'>" . $row[3] . "</td>";
echo "<td id='td4'>" . $row[4] . "</td>";
echo "<td id='td5'><a onclick='document.getElementById(\"id\").value=".$row[0]."' data-toggle='modal' data-target='#exampleModal' href=''><img data-toggle='tooltip' data-id='$row[0]' data-placement='top' title='Edit' src='img/edit.svg' height='25'></a></td>";
echo "<td id='td6'><a id='btn_link' href='php/Delete.php?id=".$row[0]."'><img data-toggle='tooltip' data-placement='top' title='Delete' src='img/delete_2.svg' height='25'></a></td>";
//echo "<td id='td5'><button type='button' class='btn btn-danger'>Delete</button></td>";
echo "</tr>";
}
}
?>
表中:
readings
此复合索引应加快(code, date, value)
CREATE INDEX your_idx ON readings (code, date, value);
子查询的速度,使MySQL可以轻松找到每个组的最小日期(并且还可以使GROUP BY
子句更容易限制甚至在{{1 }}。
我编辑了答案,将WHERE
包括在索引中,以便您的GROUP BY
中的所有列都被索引覆盖。