PHP:帮助执行一系列查询
我有一个方法,在满足特定条件的表中循环所有行,然后检查行中的一列是否出现在文本中。方法如下:PHP:帮助执行一系列查询,php,sql,mysql,Php,Sql,Mysql,我有一个方法,在满足特定条件的表中循环所有行,然后检查行中的一列是否出现在文本中。方法如下: public function isRecipeType($ingredients, $type) { $rows = $this->fetchAll($this->select()->where("type = ?", $type)); foreach($rows as $row) { if((strpos($ingredients, $ro
public function isRecipeType($ingredients, $type)
{
$rows = $this->fetchAll($this->select()->where("type = ?", $type));
foreach($rows as $row)
{
if((strpos($ingredients, $row->name)) !== false)
{
return true;
}
}
}
不过,这要花很长时间。如何加快速度(不从表中删除行)?首先,您是否在
type
列中定义了索引?由于这是搜索中的唯一条件,您希望它是一个高效的条件。您不能用SQL完成所有操作吗
已更正-未经测试-示例:
"... WHERE `type`=? AND FIND_IN_SET(name, `$ingredients`) > 0 LIMIT 1"
// return TRUE if a row is found
要使
FIND_IN_SET
起作用,值必须用逗号分隔,因此您可能必须转换$components
变量。您试图解决的问题可以表示为“是否存在类型为X、名称包含文本Y的行?”
这是一个数据库可以回答的问题,而无需用PHP编写循环。使用数据库更快,数据库可以访问比您更多的有关调优的信息。为了回答查询,基本上从数据库(可能是通过网络)将与该类型匹配的表的整个子集下载到PHP处理器是低效的。让DB为您做这项工作。它也更容易阅读,因为SQL是一种声明性语言,而PHP解决方案是必需的
public function isRecipeType($ingredients, $type)
{
$sql = "SELECT COUNT(*) AS c ".
"FROM table ".
"WHERE type = ? ".
" AND ? LIKE CONCAT('%', name, '%')";
$rows = execute($sql, $type, $ingredients);
$row = $rows[0];
return $row["c"] > 0;
}
这使用MySQL语法,如果您使用另一个数据库,则将SQL的最后一行替换为
" AND ? LIKE '%' || name || '%'";
我在你的代码中发明了一个execute
方法,我不知道你使用的是哪一个数据库访问层,但毫无疑问你也可以访问类似的东西
另一个答案是,确保在type
列上有索引。该语句的执行计划是:找到所有具有匹配类型的行(使用索引),然后遍历数据并应用类似的方法
除非超过(例如)10%的行与类型列匹配,否则顺序读取所有数据(即不使用索引)将比使用索引识别行然后随机访问读取它们更快。但是数据库会知道是否是这种情况,创建索引不会有什么坏处,然后数据库可以根据这个条件使用它或不使用它。我认为您的代码很好。查询需要多长时间?这就是我讨厌ORMs的原因。与SQL不同,当您发布“查询”时,没有人知道实际的表结构。首先,您必须使用SQL重写它,并在此处发布查询。带着$INGREDIENTS的样品,请听我说。我还建议使用一个简单的
选择count(*)
,如果有1个或多个结果,则返回true,否则返回false。@meagar,很好的一点,这只是一个简单的示例,但可以对其进行优化以更好地工作。。。。虽然只返回第一个匹配项可能比查找所有匹配项要快…@jeroen-我没有否决你的意见,但是strpos($contracents,$row->name)
将表明他正在查找name
位于$contracents
中的项目,而不是像你的查询那样。