我正在使用产品过滤器编写脚本。一切正常,但速度太慢。原因是查询太多了。 Query5选择大约200个entrys。在12个130.条目中查询12“搜索”。
是否可以使用更少的查询来更快地建立mysql连接?
<?php
$query5 = mysql_query("SELECT id,fabrikant,naam FROM producten_new WHERE icecat_cat='".secure_in($obj->icecat)."'".$selecteren."");
while($row5 = mysql_fetch_assoc($query5)){
foreach($_GET as $key=>$value){
if($key != "p" AND $key != "id" AND $key != "merk" AND $key != "submit" AND $value != "0"){
$query12 = mysql_query("SELECT COUNT(id) as aantal FROM producten_specs WHERE name='".secure_in(str_replace("_", " ", $key))."' AND value='".secure_in($value)."' AND product_id='".secure_in($row5['id'])."'");
$data12 = mysql_fetch_assoc($query12);
if($data12['aantal']){
$product_present = TRUE;
} else {
$product_present = FALSE;
break;
}
}
}
if($product_present){
echo $row5['id']."<br />";
$product_present = FALSE;
}
}
?>
感谢。
修改 好的,重新开始。我希望它更好(更快)这样:
//Select products from category and brand
$query5 = mysql_query("SELECT id FROM producten_new WHERE icecat_cat='".secure_in($obj->icecat)."'".$selecteren."");
while($row5 = mysql_fetch_assoc($query5)){
$query5_ids .= $row5['id'].", ";
}
//Remove last ','
$query5_ids = substr($query5_ids, 0, -2);
//Get all $_GET's
foreach($_GET as $key=>$value){
if($key != "p" AND $key != "id" AND $key != "merk" AND $key != "submit" AND $value != "0"){
$specs_gets .= $key.",".$value.";";
$count_gets++;
$selection .= "name='".secure_in(str_replace("_", " ", $key))."' AND value='".secure_in($value)."' OR ";
}
}
//Remove last ';'
$specs_gets = substr($specs_gets, 0, -1);
//$selection = " AND ".substr($selection, 0, -4);
$selection = substr($selection, 0, -4);
//THE query..
//$query12 = mysql_query("SELECT product_id FROM producten_specs WHERE product_id IN ('".secure_in($query5_ids)."') ".$selection." ORDER BY product_id ASC");
$query12 = mysql_query("SELECT product_id FROM producten_specs WHERE ".$selection." ORDER BY product_id ASC");
while($row12 = mysql_fetch_assoc($query12)){
if($product_hold == $row12['product_id']){
$product_hold_count++;
} else {
$product_hold_count = FALSE;
$product_hold = $row12['product_id'];
$product_hold_count = 1;
}
if($product_hold_count == $count_gets){
$query12_ids_ok .= $row12['product_id'].", ";
$count_products++;
}
}
//Remove last ','
$query12_ids_ok = substr($query12_ids_ok, 0, -2);
EDIT2 链接到网站: snip
EDIT3 更多信息:
网址示例:
index.php
?p=categorie
&id=5
&brand=Asus
&Display_inch=0
&Resolution=0
&Buldin_camera=0
&Chipset=0
&Processor-speed=2400+MHz
&Processorfamilie=0
&Hard+disk-interface=0
&Total+capacitie=500+GB
*snip (because its very long)*
&submit=Submit+Filter
数据库:
product_new(包含3500个托管) - 包含一般产品信息
id,供应商,价格,icecat_cat,名称等
1,华硕,500,笔记本电脑,K72F
product_specs(包含130.000个托管) - Contians产品规格
id,product_id,cat,name,value
1,1,处理器,处理器速度,2400 Mhz
2,1,Harddisk,Total-capacitie,500 GB
EDIT4 我越来越近,看到我的第一次编辑中的代码,只有product_id IN('。“。secure_in($ query5_ids)。”')必须添加到query12中。然后我得到了我想要的结果,速度更快!任何人吗?
答案 0 :(得分:1)
因为你是荷兰人(可以在编程中看到它)我也会用荷兰语发表我的答案。
Ik heb 1 puntje al als snelheid verbetering:omdat je $ product_niet_aanwezig op true zet doet hij de rest van de foreach wel sneller maar hij doet het niet te min。 Je kan ook een break break erin zetten。 Dan“breakt”死于uach de foreach循环。
我有一点改进:因为你将$ product_niet_aanwezig设置为true它将继续更快地执行foreach循环的其余部分,但它仍然会这样做。你也可以使用break语句来“打破”foreach循环。
答案 1 :(得分:1)
您应该首先考虑验证“where”条件中使用的所有键的索引。 (例如,表producten_specs中的名称,值,product_id)
query12只能被调用一次:你的循环应该构建一个大的条件,然后只发送一个查询。当你正在使用“count”时,你应该能够构建像
COUNT(id)FROM producten_specs WHERE [循环中构建的条件] GROUP BY product_id (虽然这可能不完全准确)
我的2美分:)
答案 2 :(得分:1)
您的代码
我无法看到你的代码有什么问题,因为我是意大利语,我不明白该脚本背后的真实逻辑。尽管如此,在我看来,你正在运行一个循环,它将执行数千个查询,或只执行一个(因为if条件),我建议使用PDO语句以某种方式缓存查询并使他们第二次跑得更快。
PDO发烧
由于第二个查询是在循环内执行的,我建议你使用PDO来存储语句,每次执行语句都会更快。
我在这里引用手册:
通过使用准备好的声明 应用程序避免重复 分析/编译/优化循环。这个 意味着准备好的陈述使用 资源减少,因此运行得更快
我想让你注意到PDO也阻止了SQL注入:
[...]开发人员可以确保不会发生SQL注入[...]
<强>索引强>
您必须在数据库端设置索引,以便查询特定表将花费更少的时间。基本上SQL索引与书籍索引类似,它们提供了一种快速查找信息的方法。
答案 3 :(得分:0)
得到了!!谢谢合作!
//Producten selecteren uit categorie en merk
$query5 = mysql_query("SELECT id FROM producten_new WHERE icecat_cat='".secure_in($obj->icecat)."'".$selecteren."");
while($row5 = mysql_fetch_assoc($query5)){
$query5_ids .= $row5['id'].", ";
}
//Laatste , weg halen
$query5_ids = substr($query5_ids, 0, -2);
//Gets op een rijte zetten
foreach($_GET as $key=>$value){
if($key != "p" AND $key != "id" AND $key != "merk" AND $key != "submit" AND $value != "0"){
$specs_gets .= $key.",".$value.";";
$aantal_gets++;
$uiteindelijk_selecteren .= "name='".secure_in(str_replace("_", " ", $key))."' AND value='".secure_in($value)."' OR ";
}
}
//Laatste ; weg halen
$specs_gets = substr($specs_gets, 0, -1);
//$uiteindelijk_selecteren = " AND ".substr($uiteindelijk_selecteren, 0, -4);
$uiteindelijk_selecteren = substr($uiteindelijk_selecteren, 0, -4);
//Overeenkomend met de get's selecteren
$query12 = mysql_query("SELECT product_id FROM producten_specs WHERE product_id IN (".secure_in($query5_ids).") AND ".$uiteindelijk_selecteren." ORDER BY product_id ASC");
while($row12 = mysql_fetch_assoc($query12)){
if($product_onthouden == $row12['product_id']){
$product_onthouden_aantal++;
} else {
$product_onthouden_aantal = FALSE;
$product_onthouden = $row12['product_id'];
$product_onthouden_aantal = 1;
}
if($product_onthouden_aantal == $aantal_gets){
$query12_ids_ok .= $row12['product_id'].", ";
$aantal_producten++;
}
}
//Laatste , weg halen
$query12_ids_ok = substr($query12_ids_ok, 0, -2);