非常慢最小值按查询分组

时间:2018-11-20 10:52:35

标签: mysql

以下查询:

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" |

1 个答案:

答案 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中的所有列都被索引覆盖。