优化搜索功能MySQL或PHP明智

尼古拉斯·拉辛(Nicolas Racine)

经过几次测试后,我意识到如果查询的某些单词很短(2〜3个字母),我的搜索方法将无法很好地执行。

我进行搜索的方式是,对访问者输入的字符串中的每个单词进行MySQL查询,然后过滤每个单词的结果以查看每个单词是否都具有该结果。一旦所有单词都返回一个结果,它就会与之匹配并向访问者显示该结果。

但是我想知道这是否是一种有效的方法。在保持相同功能的同时,还有什么更好的方法吗?

目前,我拥有的代码大约需要.7Sec来进行MySQL查询。其余的内容都在.1Sec之内。通常,我不会很在意我的搜索是否采用.7Sec,但是我想创建一个“ LiveSearch”,并且至关重要的是,它的加载速度要快于此。

这是我的代码

    public static function Search($Query){
        $Querys = explode(' ',$Query);
        foreach($Querys as $Query)
        {
            $MatchingRow = \Database\dbCon::$dbCon -> prepare("
                SELECT
                    `Id`
                FROM
                    `product_products` as pp
                WHERE
                    CONCAT(
                        `Id`,
                        ' ',
                        (SELECT `Name` FROM `product_brands` WHERE `Id` = pp.BrandId),
                        ' ',
                        `ModelNumber`,
                        ' ',
                        `Title`,
                        IF(`isFreeShipping` = 1 OR `isFreeShippingOnOrder` = 1, ' FreeShipping', '')
                    )
                LIKE :Title;
                ");
            $MatchingRow -> bindValue(':Title','%'.$Query.'%');
            try{
                $MatchingRow -> execute();
                foreach($MatchingRow -> fetchAll(\PDO::FETCH_ASSOC) as $QueryInfo)
                    $Matchings[$Query][$QueryInfo['Id']] = $QueryInfo['Id'];
            }catch(\PDOException $e){
                echo 'Error MySQL: '.$e->getMessage();
            }
        }
        $TmpMatch = $Matchings;
        $Matches = array_shift(array_values($TmpMatch));
        foreach($TmpMatch as $Query)
        {
            $Matches = array_intersect($Matches,$Query);
        }
        foreach($Matches as $Match){
            $Products[] = new Product($Match);
        }
        return $Products;
    }
佐特

正如其他人已经建议的那样,全文搜索是您的朋友。

逻辑应该或多或少像这样。

  • 在您的“ product_products”表中添加一个文本列,例如“ FtSearch”
  • 编写一个仅运行一次的小脚本,在该脚本中,您需要为每个现有产品编写要在“ FtSearch”列中搜索的文本。当然,这是您在查询中撰写的文本(id +品牌名称+标题等,包括FreeShipping部分)。您可能只用一条SQL语句即可完成此操作,但是我手头没有mysql,因此无法为您提供代码...您可能可以自己找到它。
  • 在“ FtSearch”列上创建全文索引(在填充FtSearch列之后执行此操作可以节省一些执行时间)。
  • 现在,您必须添加必要的代码,以确保每次插入/更新搜索字符串中涉及的任何字段时,也要插入/更新搜索字符串。请注意此处,因为这不仅包括“ product_product”的“ Title”,“ ModelNumber”和“ FreeShipping”,还包括“ product_brand”的“ Name”。这意味着,如果product_brand的名称已更新,则必须重新生成具有该品牌的所有产品的所有搜索字符串。这可能会有点慢,具体取决于该品牌绑定了多少产品。但是,我认为品牌更改名称的情况并不常见,如果更改,它肯定会发生在通常可以接受的某种管理界面中。
  • 此时,您可以使用MATCH构造查询表,这是使用当前方法可以更快地获得的方式。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章