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
中的项目,而不是像你的查询那样。