PHP 脚本优化 - MySql 搜索和排序

标签 php mysql optimization sorting

我开发了一个相当简单的脚本来搜索数据库,然后根据使用的搜索词对结果进行排序,因此首先尝试获得最相关的结果。

现在这在我的本地机器上运行良好,在我进行排序之前,在我雇用的网络服务器上运行正常,但是一旦排序完成,网络服务器上的搜索时间就大大增加了。

我在下面发布的内容已尽我所能进行了优化,因此我正在寻求更好的排序算法方面的帮助,甚至可能是查询数据库的更好方法,以帮助加快排序时间!

现在关于我正在使用的东西的一些信息我需要允许搜索 3 个或更多字母,例如 cat 或 car,我无法更改 mysql 服务器的自然搜索词长度限制,所以我不能使用mysql 的自然语言搜索,因此我正在执行我目前拥有的查询。

此外,平均搜索可以很容易地返回 100-15000 个结果,数据库包含大约 20000 个条目

任何帮助将不胜感激

<?php

require_once 'config.php';

$bRingtone = true;

$aSearchStrings = $_POST["searchStrings"];

$cConnection = new mysqli($dbhost, $dbuser, $dbpass, $dbname);

if (mysqli_connect_errno())
{
    exit();
}

$sTables = array("natural", "artificial", "musical", "created");

$aQueries = array();

foreach ($sTables as $sTable)
{
    $sQuery = "SELECT filename, downloadPath, description, imageFilePath, keywords FROM `$sTable` WHERE";

    $sParamTypes = "";
    $aParams = array();

    $iCount = 0;

    foreach ($aSearchStrings as $sString)
    {
            $sParamTypes .= "ss";

            $aParams[] = "%,$sString%";
            $aParams[] = "$sString%";

            $sQuery .= $iCount++ == 0 ? " (keywords LIKE ? OR keywords LIKE ?)" : " AND (keywords LIKE ? OR keywords LIKE ?)";
    }

    array_unshift($aParams, $sParamTypes);

    $aQueries[$sQuery] = $aParams;
}

$aResults = array();

foreach ($aQueries as $sQuery => $aParams)
{
    if ($cStmt = $cConnection->prepare($sQuery))
    {
            $aQueryResults = array();

            call_user_func_array(array($cStmt, 'bind_param'), $aParams);

            $cStmt->execute();

            $cStmt->bind_result($sFileName, $sDownloadPath, $sDescription, $sImageFilePath, $sKeywords);

            while($cStmt->fetch())
            {
                    if ($bRingtone)
                    {
                            $sFileName = $_SERVER['DOCUMENT_ROOT'] . "/m4r/" . str_replace(".WAV", ".M4R", $sFileName);
                            if (file_exists($sFileName))
                            {
                                    $sDownloadPath = str_replace("Sounds", "m4r", str_replace(".WAV", ".M4R", $sDownloadPath));
                                    $aResults[$sDownloadPath] = array($sDownloadPath, $sDescription, $sImageFilePath, $sKeywords, $aSearchStrings);
                            }
                    }
            }

            $aResults = array_merge($aResults, $aQueryResults);

        $cStmt->close();
    }
}

$cConnection->close();

$aResults = array_values($aResults);

function in_arrayi($needle, $haystack) {
    return in_array(strtolower($needle), array_map('strtolower', $haystack));
}

function keywordSort($a, $b)
{
    if ($a[0] === $b[0]) return 0;

    $aKeywords = explode(",", $a[3]);
    $bKeywords = explode(",", $b[3]);

    foreach ($a[4] as $sSearchString)
    {
        $aFound = in_arrayi($sSearchString, $aKeywords);
        $bFound = in_arrayi($sSearchString, $bKeywords);

        if ($aFound && !$bFound)
        {
            return -1;
        }
        else if ($bFound && !$aFound)
        {
            return 1;
        }
    }

    return 0;
}

usort($aResults, "keywordSort");

foreach ($aResults as &$aResult)
{
    unset($aResult[3]);
    unset($aResult[4]);
}

echo json_encode($aResults);

?>

最佳答案

在必须拆分字段代码端的同时对大量数据进行排序会很慢。而不是优化,我会认真推荐另一种方法,例如全文索引。一旦开始工作,它真的非常整洁。

如果全文确实不是一个选项,我建议将关键字拆分到一个单独的表中。这样,您可以在分组后根据计数进行排序。例如……

SELECT d.*, COUNT(k.id) AS keywordcount
FROM data d
    INNER JOIN keywords k ON (d.id = k.dataid)
WHERE k.value IN ('keyword1', 'keyword2', 'keyword3')
GROUP BY d.id
ORDER BY keywordcount

在另一个 PSish 类型的注释中,您可能可以通过联合选择然后排序来加快速度,而不是独立运行它们。

关于PHP 脚本优化 - MySql 搜索和排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5043606/

相关文章:

php - MySql使用主索引而不是多列索引!

使用 magento/bin 设置 :di:compile 在 docker 中耗尽 PHP 内存大小

javascript - child 糖果 Hackerrank 挑战 : optimising the solution

c - C 版和 Fortran90 : optimization for filling subarrays before MPI_Gather

php - 从每个类别中选择最近 3 条新闻 - 两个表 - (MySQL - PHP)

javascript - jQuery:确定[服务器的]文档根目录

mysql - 自定义列的多个值

mysql - 优化MYSQL排名mod查询

php - Num rows 返回错误的数字

c++ - 基于 C++ 中的属性对一类对象进行分区的优化方法