我已经设置了一个PHP-MySQL。我有一个devicevalue
表,它的结构就像这个
devId | vals | date | time
xysz | 23 | 2020.02.17 | 22.06
abcs | 44 | 2020.02.31 | 22.07
vals列保存温度值。任何登录我的网络应用程序的用户都只能访问某些设备。
以下是的步骤
- 在我的网站上"用户";从和到的日期中选择他想要查看的数据&提交
- 然后这些日期被传递一页";getrecords.php",其中有许多选择查询(许多处于循环中(,以获取所需格式的过滤数据
问题是这个表保存了近200-300万条记录。在每一个where子句中,我都必须将添加到和条件中的。这导致在整个表中进行搜索。
我的问题是,我有没有办法在步骤1中获得临时表,该表将根据给定的两个日期仅具有某些行,然后我在其他页面上的所有查询都将针对该临时表?
编辑:如果date
列是文本字符串,则必须将其转换为类型为DATE
或TIMESTAMP
的列,否则将永远无法从该表中获得良好的性能。MySQL服务器中有大量的优化代码,可以有效地处理时间/日期数据类型。如果将日期或时间存储为字符串,则会破坏所有优化代码。
然后,在date
列上设置一个索引,如下所示。
CREATE INDEX date_from_to ON devicevalue (`date`, devId, vals, `time` );
它被称为覆盖索引,因为仅使用它就可以满足整个查询。
然后,在您的查询中使用
WHERE date >= <<<fromdate>>>
AND date < <<<todate>> + INTERVAL 1 DAY
正确地进行索引可以消除创建临时表的需要。
如果您的查询具有类似于`WHERE devId=<lt>gt;在它中,您需要这个索引来代替(或添加(。
CREATE INDEX date_id_from_to ON devicevalue (devId, `date`, vals, `time` );
如果您有机会更改此表的布局,请将date
和time
列组合为TIMESTAMP数据类型的一列。如果您这样做,我上面向您展示的WHERE子句仍然可以正常工作。一切都会一样快。
SQL可以简单快捷地解决您的问题。有了良好的数据选择和适当的索引,几百万条记录就是一个中等大小的表。
简单回答:不。不要设计需要在会话之间生存的临时表。
更长的答案:
在你的应用程序中构建日期范围将从一个页面传递到下一个页面,然后在<form> <input type=text...>
中使用这些值作为初始值
然后确保为可能的查询提供了一个良好的复合索引。但是,要做到这一点,你必须了解可能需要什么。您可能需要少量的多列索引。
您可能可以根据表单条目构建SELECT
。我很少需要使用一个以上的查询,但它大多是"构造的";基于表单的飞行。
对于date
和time
,很少有单独的列是一个好主意。例如,说一天中午到第二天中午非常困难。合并为DATETIME
或TIMESTAMP
。
O.Jones说了很多我通常会在这里补充的话。