2015-05-27 72 views
1

使用我创建的数据库,我可以运行以JSON格式输出数据的搜索查询,然后将它们发送回我的网页。相当标准。针对PHP的JSON响应太大?

$searchQuery = "SELECT * FROM alldata where $searchBy like '%$searchValue%'" ; 
$searchResult = mysqli_query($con, $searchQuery); 

while ($row = mysqli_fetch_row($searchResult)) { 

$item = array(); 
    $item["dateReceived"] = convertDate($row[1]);  
    $item["quoteCost"] = $row[15]; 
    $item["quoteNumber"] = $row[16]; 
    $item["quoteExpDate"] = convertDate($row[17]);  
    $item["comments"] = $row[21];  

    $output[] = $item; 
    } 

$out = array('aaData' => $output);  
echo json_encode($out); 

当我的查询太笼统了,某些东西失败了,我不确定它在哪里。

我从服务器得到的回应是:

Fatal error : Allowed memory size of 134217728 bytes exhausted (tried to allocate 14680165 bytes) in C:\xampp\htdocs\....php</b> on line <b>74</b><br /> 

我的内存限制在php.ini中设置为:

memory_limit=128M 

如果我去到MySQL,写SELECT * FROM ALLDATA WHERE name like "%a%";我得到约35,000行,每行约20列,但只需要一秒钟。

我可以根据表查询的数量非常小 - 我能做些什么来解决这个问题,以便我的用户可以运行更通用的查询?

+4

**警告**:当使用'mysqli'时,您应该使用参数化查询和['bind_param'](http://php.net/manual/en/mysqli-stmt.bind-param.php)来添加用户数据**不要**使用字符串插值来实现这一点,因为您将创建严重的[SQL注入漏洞](http://bobby-tables.com/)。**从不**将'$ _POST'数据直接进入一个查询 – tadman

+1

如果你想要做这样的事情,128MB看起来真的很低,为什么不这样做呢,看看你是否能获得更多的数据?Mi ght也调查分页。 – tadman

+1

第一件事是只返回所需的数据,所以在你的select中删除*并实际放入你正在处理的列名。 – geggleto

回答

1

用户不希望在一个页面中同时看到所有35,000行。

这会:

(1)增加脚本的执行时间。

(2)可能会导致浏览器崩溃,试图显示如此多的数据。

为了有效执行脚本,请使用分页和/或对查询设置限制。

+0

是的,我认为你们都是对的。这里每个人的明确抗议意味着我可能要重新考虑这一点....... –

+0

你如何在前端显示你的数据?带有数据表的 –

+0

。我会接受这个 - 但我很欣赏所有人都留下的回应。我会诉诸LIMIT,并将其设置为500或其他。这给了他们足够的控制。 –

2
  1. 定义输出数组长度upfront => $ output = array(mysql_count($ query));
  2. 包括一个限制你的SQL查询
1

您可以尝试通过设置

memory_limit=256M 

,或者如果你只使用它为查询增加内存,您可以临时改变以及

<?php 
    ini_set('memory_limit', '256M'); 

当然,用你需要的适当数量替换'256M'。 尽管如此,一定要将它恢复到之前的状态。你不希望PHP消耗太多内存。

我也推荐96Levels的答案。使用分页更有效地管理内存。但是,如果您确实想要一次处理所有数据,则需要增加内存大小。

+0

如果我正在使用分页,但没有显示的结果将不可用于“DataTables”内置搜索,但我不这么认为。目标是让所有这20行返回到用户想要查看的行数。如果他们想做一个超级通用搜索,并花5分钟来加载表,那是他们的业务,而不是我的。我不会推荐它,但我也不希望他们获得0结果。 –

1

你应该做的第一件事是在php.ini中增加memory_limit for php(搜索memory_limit = 128M并将其设置为一个更高的值。不要将值设置得太高或者一些请求会导致使用如果脚本在使用中效率不高,可以使用ini_set('memory_limit', '256M');提高限制(如果ini_set函数未被禁用(通常托管提供程序禁用所以资源不会被滥用))。

在PHP中增加内存限制只会暂时解决您的问题,如果您的数据库正在增长。

您使用查询的方式是糟糕的体系结构。查询不应该在没有LIMIT的情况下执行,特别是对于大型数据集。

这里有几件事情需要注意,除了提高已经很低的memory_limit。你现在遇到的问题(如果确实是由自己执行的查询快速返回响应)只是为结果数组/对象及其转换后的字符串分配足够空间的问题;然而,其他问题现在或未来可能会导致这种情况。我可以在这里找到一些可以帮助你一劳永逸的解决方法。

1-向您的请求添加限制和页面参数,以便您可以获得分页结果。

2-在MySQL中为您正在搜索的字段使用适当的索引。如果您正在使用varchar或text字段进行搜索,则最好使用全文索引而不是常规B树索引。 Full-Text Search Functions

3-如果由于某种原因,你不能使用全文搜索(例如:你必须使用InnoDB而不是MyISAM数据),确保你不会在字符串的开头,因为它会使用通配符“%”不正确使用索引(如果使用常规的B-Tree索引而不是全文)。

如果你非得用它,我会建议转移到全文检索(如果你想坚持到MySQL的搜索,而不是使用搜索引擎一样Apache SolrSphinx SearchElastic Search仅举几例。

+0

是的,限制绝对是要走的路。我可以把它设置得很高 - 我不认为会有问题。非常感谢! –

+0

你错过了这一点,但。尽管内存限制增加并且“现在”工作,但这并不意味着它会继续工作。至少考虑对结果进行分页,以便您不必一次处理数千条记录。 – Adon

+0

我不认为我错过了这一点。我在我的sql查询中添加了一个LIMIT,这意味着我并不需要担心PHP的内存限制。 (也许我使用“极限”这个词,并且它引用了这两个概念,这令人困惑)。 –