Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP-MySQL到JSON的性能优化_Php_Mysql_Json_Mysqli - Fatal编程技术网

PHP-MySQL到JSON的性能优化

PHP-MySQL到JSON的性能优化,php,mysql,json,mysqli,Php,Mysql,Json,Mysqli,我正在收集传感器数据,将它们存储在MySQL数据库中,并使用Highcharts中的PHP应用程序将数据作为JSON对象加载,以进行图形表示 现在我的表中有大约20万个条目。我认识到生成JSON大约需要3.5秒。我想随着更多的条目,我会变得太慢 有没有办法优化JSON的处理 以下是生成JSON的PHP代码: $sql = "SELECT time, value1, value2 from ". $feedID; $result = mysqli_query($con, $sql); while

我正在收集传感器数据,将它们存储在MySQL数据库中,并使用Highcharts中的PHP应用程序将数据作为JSON对象加载,以进行图形表示

现在我的表中有大约20万个条目。我认识到生成JSON大约需要3.5秒。我想随着更多的条目,我会变得太慢

有没有办法优化JSON的处理

以下是生成JSON的PHP代码:

$sql = "SELECT time, value1, value2 from ". $feedID;
$result = mysqli_query($con, $sql);

while ($row = mysqli_fetch_array($result)) {
    if ( $row[2] == null ) {
        $response[data][] = array( (strtotime($row['time']))*1000, (float) $row[1]);
    } else {
        $response[data][] = array( (strtotime($row['time']))*1000, (float) $row[1], (float) $row[2]);
    }
}

 $return = json_encode($response);
 header('Content-type: text/json');  
 header('Content-Length: '.strlen($return)."\r\n"); 
 header('Accept-Ranges: bytes'."\r\n");
 echo $return;

我可以提出以下建议:

  • 通过将数据直接存储到JSON中,可以跳过生成JSON 使用MySQL 5.7格式化
  • 尝试对查询分页,并使用query
    LIMIT
    OFFSET
  • 尝试使用附加标志优化
    json\u encode
    ,例如
    json\u UNESCAPED\u UNICODE
    (可在
    PHP5.4+
    中获得)-
    json\u encode(array(),json\u UNESCAPED\u UNICODE)
    -这将保持UTF-8字符不变,但这取决于您的数据,您将获得轻微的性能提升。查看所有json_编码选项

我想您可以先优化查询:

SELECT unix_timestamp(time)*1000 as time, value1, value2 from ". $feedID." 
WHERE value2 is not null";
接下来,无论如何,你可能不需要在图表上有这么多数据。尝试立即减少highchart上显示的数据量

例如,当你在寻找如何到达你所在城市的郊区时,谷歌地图不会载入整个世界。在图表上渲染200k行的速度会非常慢,所以即使调整后端,前端也会被卡住。 在整个时间段内,您可以选择以天/月为单位呈现数据,例如:

SELECT
   month(`time`) as mo,
   year(`time`) as `year`,
   avg(value1) as value1,
   avg(value2) as value2
FROM table
WHERE
    value2 is not null
GROUP by year(`time`), month(`time`)
考虑到上面的查询,您可能希望更改现有的表,这样就不需要计算月份和年份,但您更希望将其存储在写操作中。 当您写入数据库时,您可能还希望在另一个表/存储器中具有聚合数据,以便可以轻松地访问它

所以,通常的答案是:尽量减少数据量。 我甚至无法想象现实世界中需要在图表上呈现200000条记录的情况

生成JSON大约需要3.5秒

而是意味着
json\u编码($response)需要3.5秒-真的是这样吗?你的剧本没有时间安排。如果您的意思是数据到达客户端需要3.5秒,则需要将以下内容分开:

  • 从数据库中检索数据并构建aray的时间
  • json_encode()的时间
  • 输出数据的时间
  • 数据穿过网络的时间
  • 在客户端解析数据的时间
假设成本在json_encode()中(或者在构建非常大的数组时——这将导致内存问题),那么您应该以增量方式构建输出

header('Content-type: text/json');
$sql = "SELECT time, value1, value2 from ". $feedID;
$result = mysqli_query($con, $sql);

print "{ "data" : ";
$join="[\n";
while ($row = mysqli_fetch_assoc($result)) {
    print $join;
    $response = array( 
        (strtotime($row['time']))*1000
        , (float) $row['value1']
        );
    if ($row['value2']!==null) {
        $response[]=(float) $row['value2'];
    }
    print json_encode($response);
    $join=",\n";
}   
print "]\n}\n";
我的表中有大约20万个条目

你的显示器上有多少像素?你在绘制什么样的图表

您最大的胜利将来自处理更少的数据


顺便说一句:您认为
标题('Accept-Ranges:bytes')怎么样?“\r\n”)正在做什么?您的代码不接受范围。

我看到的优化的唯一方法是缓存json文件使用memcached/Redis和SERVICE缓存文件,或者在后端生成json_编码的字符串并将其存储在数据库/磁盘中,如果需要,每5-10分钟用cronjob刷新一次。我不确定,但是如果
$response[data][]
不是常量,使用带引号的“数据”可能会更快,因为PHP可能正在将常量用作字符串的错误写入日志文件,因为没有定义。然后,在
(float)$row[1]
中强制转换要浮动的列,我认为如果该列具有所需的值,则不需要强制转换,因为您随后将编码为json,json基本上是一个字符串。我不确定这是否是一个有效的回复,所以我在评论中留下了它。谢谢你,亚历克斯$响应[数据][]是我的错误。已修复,但没有性能改进。关于float强制转换,如果我不将值强制转换为float,它将在带括号的json中。像“235”。我怀疑highcharts是否真的需要所有200k的测量值。您始终可以将数据聚合到某个合理的阈值—一分钟、一小时或一天。因此,您可以大大减小数组的大小。前两个显然不相关。我尝试了“JSON\u UNESCAPED\u UNICODE”标志,但没有明显的效果。感谢symcbean的重播。按照计时:检索表1.8s,构建json 0.23s,输出0.007s,总计约为2秒。今天数据传输为500ms(gzip)。我用Highcharts股票来比较温度和湿度。数据探索非常好,我可以放大到30秒的间隔。嗨,Nemoden,您提出的查询优化将检索表的时间从1.8秒缩短到了0.5秒。这是一个巨大的进步。非常感谢。从长远来看,我需要找到一种方法来减少数据量。很高兴能帮助你,@Rene